Firmy's blog Firmy's blog http://firmianay.github.io/ Tue, 04 Aug 2020 12:35:27 +0000 Tue, 04 Aug 2020 12:35:27 +0000 Jekyll v3.8.7-CVE.2020.14001 Firmalice - Automatic Detection of Authentication Bypass Vulnerabilities in Binary Firmware <h2 id="简介">简介</h2> <p>这篇文章提出了 Firmalice,一种二进制分析框架,以支持对嵌入式设备上所运行的固件进行分析。Firmalice 构建在符号执行引擎之上,并且提供了程序切片之类的技术来提高其可扩展性。此外,Firmalice 构建了一种新型的认证旁路漏洞模型,基于攻击者的能力来确定执行特权操作所需要的输入。</p> <p>Detecting authentication bypasses in firmware is challenging for several reasons:</p> <ul> <li>The source code of the firmware is not available.</li> <li>Firmware often takes the form of a single binary image that runs directly on the hardware of the device, without an underlying operating system.</li> <li>Embedded devices frequently require their firmware to be cryptographically signed by the manufacturer, making modification of the firmware on the device for analysis purposes infeasible.</li> </ul> <h2 id="认证旁路漏洞">认证旁路漏洞</h2> <p>Many embedded devices contain <code class="language-plaintext highlighter-rouge">privileged operations</code> that should only be accessible by <code class="language-plaintext highlighter-rouge">authorized users</code>. To protect these privileged... Thu, 14 Jun 2018 00:06:31 +0000 http://firmianay.github.io/firmalice/ http://firmianay.github.io/firmalice/ note iot symbolic angr note Driller: Augmenting Fuzzing Through Selective Symbolic Execution <h2 id="简介">简介</h2> <p>这篇文章提出了 Driller,这是一种混合漏洞挖掘工具,它以互补的方式将模糊测试和选择性混合执行结合起来,以发现隐藏更深的漏洞。模糊测试用于探索程序空间的不同区间,并使用混合执行来生成满足不同区间的输入。</p> <h2 id="driller-概述">Driller 概述</h2> <p>A core intuition behind the design of Driller is that applications process two different classes of user input: <code class="language-plaintext highlighter-rouge">general</code> input, representing a wide range of values that can be valid, and <code class="language-plaintext highlighter-rouge">specific</code> input, representing input that must take on one of a select few possible values. Conceptually, an application’s checks on the latter type of input split the application into compartments. Execution flow moves between compartments through checks against specific input, while, within a compartment, the application processes general input.</p> <p>Driller is composed of multiple components:</p> <ul> <li>Input test... Wed, 13 Jun 2018 00:06:31 +0000 http://firmianay.github.io/driller/ http://firmianay.github.io/driller/ note symbolic fuzz note AEG: Automatic Exploit Generation <h2 id="简介">简介</h2> <ul> <li>这篇论文向我们展示了如何将控制流劫持攻击的漏洞利用生成模型化为一个形式化验证问题。</li> <li>提出了预处理符号执行,这是一种新的符号执行技术。</li> <li>提出了一种通用的漏洞利用生成方法。</li> <li>构建了 AEG,这是第一个能够自动发现漏洞并生成利用获得 shell 的端到端系统。</li> </ul> <h4 id="挑战及解决方案">挑战及解决方案</h4> <ul> <li>Source code analysis alone is inadequate and insufficient. <ul> <li>We combine source-code level analysis to improve scalability in finding bugs and binary and runtime information to exploit programs.</li> </ul> </li> <li>Finding the exploitable paths among an infinite number of possible paths <ul> <li>We have developed preconditioned symbolic execution, a novel technique which targets paths that are more likely to be exploitable.</li> <li>We have developed a priority queue path prioritization technique that uses heuristics to choose likely more exploitable paths first.</li> </ul> </li> <li>An end-to-end system. <ul>... Tue, 12 Jun 2018 00:06:31 +0000 http://firmianay.github.io/aeg/ http://firmianay.github.io/aeg/ note exploit symbolic note (State of) The Art of War: Offensive Techniques in Binary Analysis <h2 id="简介">简介</h2> <p>这篇文章提出了一个二进制分析框架,并实现了许多现有的分析技术。通过将这些技术系统化地实现,可以让其他研究人员直接利用并开发新的技术。此外,在统一框架中实现这些技术可以更直接地进行比较,并确定各自的优缺点。</p> <h2 id="自动化二进制分析">自动化二进制分析</h2> <p>为了保持程序分析的可行性,往往需要在可重现性和语义理解两个方面需要进行权衡:</p> <ul> <li>可重现性:由于分析系统做出的权衡,特定的分析所发现的漏洞可能无法重现。这可能是分析操作的覆盖范围导致的,一些分析从头执行整个应用程序,因此可以推断出触发漏洞的原因,而其他一些分析只是分析了程序的某个部分,这样做可以在特定模块中发现漏洞,但无法完整地推断出触发漏洞的原因,于是无法重现。</li> <li>语义理解:一些分析缺乏对程序语义的理解。例如,动态分析能够追踪程序执行的代码,但不能理解为什么这些代码被执行或者程序输入的哪些部分导致了这样的执行。</li> </ul> <p>为了得到可重现的输入或者语义理解的能力,就需要对分析技术进行权衡。例如,高可重现性往往和低覆盖率相关,因为要想生成可重现的输入必须知道如何到达任何想要分析的代码,那么它将不能分析尽可能多的代码。另一方面,如果不能通过重现来验证漏洞,那么会产生高误报率(即并不存在漏洞)。在缺乏可重现性的情况下,这些误报必须通过启发式的方法进行过滤,反过来又会引入高漏报率。同样的,为了实现语义理解,必须存储和处理大量的数据。例如,具有语义理解能力的动态分析必须保存下程序分支的条件,而具有语义理解能力的静态分析需要适时地调整数据域。但由于系统资源有限,在分析中必须做出取舍。</p> <p>下面是一个例子,可以对不同分析技术的能力有个简单的认识:</p> <p><img src="/post_pic/2018-06-10-angr/angr_example.png" alt="" /></p> <p>对于静态分析,它可能会将全部 3 个 memcpy 调用都标记为漏洞(即使 16 行的调用其实是安全的),因为静态分析没有足够的信息来确定漏洞是否真的会发生。另外,静态分析可以得到漏洞的地点,但不能得到触发漏洞的输入。对于动态分析(例如 fuzzing),它通过制造输入来触发漏洞,所以通常有很大可能会漏掉需要精确输入的漏洞,例如第 10 行的漏洞。动态符号执行能够检测出第 10 行的错误并通过约束求解得到输入,也能判断出第 16 行没有漏洞,但是它很可能会漏掉第 30 行,因为有多个潜在的路径不会触发该漏洞。另外,在符号执行进行到循环时,可能存在路径爆炸的问题。</p> <h2 id="静态漏洞挖掘">静态漏洞挖掘</h2> <p>Static analyses can be split into two paradigms: those that model program properties as graphs and those that model the data itself.</p> <h4 id="控制流图恢复">控制流图恢复</h4> <p>CFG recovery is implemented as a recursive algorithm that disassembles and analyzes a basic block, identifies its possible exits and adds them to the CFG, and then repeats the analysis recursively until no new exits are identified.</p> <p>CFG recovery has one fundamental... Sun, 10 Jun 2018 00:06:31 +0000 http://firmianay.github.io/angr/ http://firmianay.github.io/angr/ note angr symbolic note angr 源码分析 <ul> <li><a href="#angr">angr</a> <ul> <li><a href="#project-类">Project 类</a></li> <li><a href="#load_shellcode">load_shellcode</a></li> </ul> </li> <li><a href="#cle">cle</a> <ul> <li><a href="#loader-类">Loader 类</a></li> <li><a href="#clemory-类">Clemory 类</a></li> <li><a href="#backend-类">Backend 类</a></li> <li><a href="#register_backend">register_backend</a></li> </ul> </li> <li><a href="#claripy">claripy</a></li> </ul> <p>源码版本是 7.8.6.16。推荐使用 angr-dev,以便获得更快的更新。</p> <h2 id="angr">angr</h2> <h4 id="project-类">Project 类</h4> <p>Project 类是 angr 的主类。它包含了一组二进制文件及其相互关系,然后会对这些二进制文件进行分析。</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Project</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">thing</span><span class="p">,</span> <span class="n">default_analysis_mode</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">ignore_functions</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">use_sim_procedures</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">exclude_sim_procedures_func</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">exclude_sim_procedures_list</span><span class="o">=</span><span class="p">(),</span> <span class="n">arch</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">simos</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">load_options</span><span class="o">=</span><span... Wed, 16 May 2018 00:06:31 +0000 http://firmianay.github.io/angr/ http://firmianay.github.io/angr/ code angr symbolic code pwn 34C3CTF2017 300 <ul> <li><a href="#题目复现">题目复现</a></li> <li><a href="#题目解析">题目解析</a></li> <li><a href="#漏洞利用">漏洞利用</a></li> <li><a href="#参考资料">参考资料</a></li> </ul> <h2 id="题目复现">题目复现</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ file 300 300: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5f43b102f0fe3f3dd770637f1d244384f6b2a1c9, not stripped $ checksec -f 300 RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH Yes 0 2 300 $ strings libc-2.24.so | grep "GNU C" GNU C Library (Ubuntu GLIBC 2.24-9ubuntu2.2) stable release version 2.24, by Roland McGrath et al. Compiled by GNU CC version 6.3.0 20170406. </code></pre></div></div>... Tue, 08 May 2018 00:00:00 +0000 http://firmianay.github.io/pwn_34c3ctf2017_300/ http://firmianay.github.io/pwn_34c3ctf2017_300/ ctf CTF pwn BCTF2016 bcloud <ul> <li><a href="#题目复现">题目复现</a></li> <li><a href="#题目解析">题目解析</a></li> <li><a href="#漏洞利用">漏洞利用</a></li> <li><a href="#参考资料">参考资料</a></li> </ul> <h2 id="题目复现">题目复现</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ file bcloud bcloud: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=96a3843007b1e982e7fa82fbd2e1f2cc598ee04e, stripped $ checksec -f bcloud RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH Yes 0 4 bcloud $ strings libc-2.19.so | grep "GNU C" GNU C Library (Ubuntu EGLIBC 2.19-0ubuntu6.7) stable release version 2.19, by Roland McGrath et al. Compiled by GNU CC version 4.8.2. </code></pre></div></div> <p>32 位程序,开启了... Tue, 01 May 2018 00:06:31 +0000 http://firmianay.github.io/pwn_bctf2016_bcloud/ http://firmianay.github.io/pwn_bctf2016_bcloud/ ctf ctf Symbolic Execution for Software Testing: Three Decades Later <h2 id="简介">简介</h2> <p>近几年符号执行因其在生成高覆盖率的测试用例和发现复杂软件漏洞的有效性再次受人关注。这篇文章对现代符号执行技术进行了概述,讨论了这些技术在路径探索,约束求解和内存建模方面面临的主要挑战,并讨论了几个主要从作者自己的工作中获得的解决方案。</p> <p>这算是一篇很经典很重要的论文了。</p> <h2 id="传统符号执行">传统符号执行</h2> <p>符号执行的关键是使用符号值替代具体的值作为输入,并将程序变量的值表示为符号输入值的符号表达式。其结果是程序计算的输出值被表示为符号输入值的函数。一个符号执行的路径就是一个 true 和 false 组成的序列,其中第 i 个 true(或false)表示在该路径的执行中遇到的第 i 个条件语句,并且走的是 then(或else) 这个分支。一个程序所有的执行路径可以用执行树(Execution Tree)来表示。举一个例子:</p> <p><img src="/post_pic/2018-04-29-symbolic_execution/se_tree.png" alt="" /></p> <p>函数 testme() 有 3 条执行路径,组成右边的执行树。只需要针对路径给出输入,即可遍历这 3 条路径,例如:{x = 0, y = 1}、{x = 2, y = 1} 和 {x = 30, y = 15}。符号执行的目标就是去生成这样的输入集合,在给定的时间内遍历所有的路径。</p> <p>符号执行维护了符号状态 σ 和符号路径约束 PC,其中 σ 表示变量到符号表达式的映射,PC 是符号表示的不含量词的一阶表达式。在符号执行的初始化阶段,σ 被初始化为空映射,而 PC 被初始化为 true,并随着符号执行的过程不断变化。在对程序的某一路径分支进行符号执行的终点,把 PC 输入约束求解器以获得求解。如果程序把生成的具体值作为输入执行,它将会和符号执行运行在同一路径,并且以同一种方式结束。</p> <p>例如上面的例子。符号执行开始时,符号状态 σ 为空,符号路径约束 PC 为 true。每当遇到输入语句 var = sym_input() 时,符号执行就会在符号状态 σ 中加入一个映射 var-&gt;s,这里的 s 是一个新的未约束的符号值,于是程序的前两行得到结果 σ = {x-&gt;x<sub>0</sub>, y-&gt;y<sub>0</sub>}。当遇到一个赋值语句 v = e 时,符号执行就会在符号状态 σ 中加入一个 v 到 σ(e) 的映射,于是程序执行完第 6 行后得到 σ = {x-&gt;x<sub>0</sub>, y-&gt;y<sub>0</sub>, z-&gt;2y<sub>0</sub>}。</p> <p>当每次遇到条件语句 if(e) S1 else... Sun, 29 Apr 2018 00:06:31 +0000 http://firmianay.github.io/symbolic_execution/ http://firmianay.github.io/symbolic_execution/ note symbolic note pwn HITCONCTF2016 Sleepy_Holder <ul> <li><a href="#题目复现">题目复现</a></li> <li><a href="#题目解析">题目解析</a></li> <li><a href="#漏洞利用">漏洞利用</a></li> <li><a href="#参考资料">参考资料</a></li> </ul> <h2 id="题目复现">题目复现</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ file SleepyHolder SleepyHolder: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=46f0e70abd9460828444d7f0975a8b2f2ddbad46, stripped $ checksec -f SleepyHolder RELRO STACK CANARY NX PIE RPATH RUNPATH FORTIFY Fortified Fortifiable FILE Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH Yes 0 2 SleepyHolder $ strings libc.so.6 | grep "GNU C" GNU C Library (Ubuntu GLIBC 2.23-0ubuntu3) stable release version 2.23, by Roland McGrath et al. Compiled by GNU CC version 5.3.1 20160413. </code></pre></div></div> <p>64 位程序,开启了... Fri, 27 Apr 2018 00:06:31 +0000 http://firmianay.github.io/pwn_hitconctf2016_sleepy_holder/ http://firmianay.github.io/pwn_hitconctf2016_sleepy_holder/ ctf ctf ROPdefender: A Detection Tool to Defend Against Return-Oriented Programming Attacks <h2 id="简介">简介</h2> <p>论文设计并实现了工具 ROPdefender,可以动态地检测传统的 ROP 攻击(基于return指令)。ROPdefender 可以由用户来执行,而不依赖于源码、调试信息等在现实中很难获得的信息。</p> <p>ROPdefender 基于二进制插桩框架 Pin 实现,作为一个 Pintool 使用,在运行时强制进行返回地址检查。</p> <h2 id="背景">背景</h2> <p>现有的 ROP 检测方法会维护一个 shadow stack,作为返回地址的备份。当函数返回时,检查返回地址是否被修改。</p> <p>这种方法有个明显的缺陷,它只能检测预期的返回(intended return),而对于非预期的返回(unintended return)无效。</p> <p>intended instruction 是程序中明确存在的指令。而 unintended instruction 是正常指令通过偏移得到的指令。举个例子:</p> <p>intended instruction:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>b8 13 00 00 00 mov $0x13, %eax e9 c3 f8 ff ff jmp 3aae9 </code></pre></div></div> <p>偏移两个十六进制后的 unintended instruction:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>00 00 add %al, (%eax) 00 e9 add %ch, %cl c3 ret </code></pre></div></div> <p>这样的返回不会被备份到 shadow stack 中,因此也不会被检测到。</p> <p>另外,如果攻击者修改的不是返回地址,而是函数的 GOT 表,则同样不会被检测到。</p> <h2 id="解决方案">解决方案</h2> <p>ROPdefender 同样也使用 shadow stack 来储存每次函数调用的返回地址。在每次函数返回时进行返回地址检查。</p> <p>与现有方法不同的是:</p> <ul> <li>ROPdefender 会检查传递给处理器的每个返回指令(基于JIT插桩工具),这样即使攻击者使用 unintended instruction 也会被检测到</li> <li>ROPdefender 还能处理各种特殊的情况</li> </ul> <p>整体思想如下图所示:</p> <p><img src="/post_pic/2018-04-22-ropdefender/approach.png" alt="" /></p>... Sun, 22 Apr 2018 00:06:31 +0000 http://firmianay.github.io/ropdefender/ http://firmianay.github.io/ropdefender/ note rop note