资源描述
新型代码复用新型代码复用攻击及防御攻击及防御中国科学院中国科学院 信息工程研究所信息工程研究所陈李维陈李维主要内容研究背景研究背景粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的代码复用攻击的代码复用攻击COOP和和FOPJIT-ROP不可读保护不可读保护CPI总结总结代码复用攻击分类根据配件类型、配件之间连接关系、及提出根据配件类型、配件之间连接关系、及提出的时间关系等分类,代码复用攻击可以分为的时间关系等分类,代码复用攻击可以分为两大类:两大类:经典代码复用攻击经典代码复用攻击(上一讲内容)(上一讲内容)都是在都是在2010年以前提出的攻击方法。主要考虑绕过年以前提出的攻击方法。主要考虑绕过不可执行位保护,实现图灵完备攻击,基本不考虑不可执行位保护,实现图灵完备攻击,基本不考虑针对代码复用攻击的防御。针对代码复用攻击的防御。新型代码复用攻击新型代码复用攻击大多是在大多是在2010年以后提出的攻击方法。考虑到了对年以后提出的攻击方法。考虑到了对代码复用攻击的防御,思考如何绕过这些针对性的代码复用攻击的防御,思考如何绕过这些针对性的防御方法。防御方法。代码复用攻击的防御分类代码复用攻击的防御方法也可以分为两大类:代码复用攻击的防御方法也可以分为两大类:随机化方法随机化方法:ASLR为代表性方法为代表性方法将系统中代码地址随机化,使得攻击者无法找到对将系统中代码地址随机化,使得攻击者无法找到对应配件的真实地址,从而无法进行攻击。应配件的真实地址,从而无法进行攻击。异常行为检测异常行为检测:CFI为代表性方法为代表性方法代码复用攻击的代码执行过程和正常程序过程完全代码复用攻击的代码执行过程和正常程序过程完全不同。不同。分析检测程序执行过程,如果发现程序执行过程和分析检测程序执行过程,如果发现程序执行过程和正常过程不同,就认为发生了攻击。正常过程不同,就认为发生了攻击。从从随机化防御随机化防御角角度,代码复用攻度,代码复用攻击及防御之间的击及防御之间的相互发展关系。相互发展关系。ASLR细粒度细粒度随机化随机化新的攻击方法:新的攻击方法:JIT-ROP,代码,代码复用攻击结合内复用攻击结合内存信息泄露存信息泄露新的防御方法:新的防御方法:不可读保护不可读保护攻防发展脉络从从异常行为检测异常行为检测角度,代码复用角度,代码复用攻击及防御之间攻击及防御之间的相互发展关系。的相互发展关系。CFI粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的攻击的攻击新型代码复用攻新型代码复用攻击:击:COOP新的防御方法:新的防御方法:CPI攻防发展脉络主要内容研究背景研究背景粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的代码复用攻击的代码复用攻击COOP和和FOPJIT-ROP不可读保护不可读保护CPI总结总结CFI的缺点CFI是异常行为检测的代表性防御方法,具是异常行为检测的代表性防御方法,具有很好的防御效果,但是也有以下缺点:有很好的防御效果,但是也有以下缺点:实用性不高,没有被真实系统采用。实用性不高,没有被真实系统采用。实现复杂实现复杂性能损耗过高性能损耗过高依赖依赖CFG(控制流图)(控制流图)一个完全精确的一个完全精确的CFG是不可能生成的是不可能生成的对于不违反程序对于不违反程序CFG的攻击无能为力的攻击无能为力粗粒度CFI思想的来源思想来源思想来源1:对:对CFI的优化的优化降低复杂性,提高效率降低复杂性,提高效率不依赖不依赖CFG思想来源思想来源2:对代码复用攻击和正常程序行为:对代码复用攻击和正常程序行为之间特征的分析之间特征的分析对代码复用攻击和正常程序的行为特征进行更对代码复用攻击和正常程序的行为特征进行更深入的分析,从中获得更加通用有效的深入的分析,从中获得更加通用有效的有区分有区分度的度的行为特征行为特征程序行为特征分析代码复用攻击代码复用攻击配件长度很短配件长度很短,也就是说,也就是说间接跳转指令频率很间接跳转指令频率很高高,以上两种说法,以上两种说法等价等价间接跳转指令间接跳转指令跳转目标不正常跳转目标不正常正常程序行为正常程序行为间接跳转指令间接跳转指令频率不高频率不高间接跳转指令间接跳转指令跳转目标正常且有规律跳转目标正常且有规律程序行为特征分析代码复用攻击代码复用攻击间接跳转指令(间接跳转指令(call,ret,jump)的跳转目标:)的跳转目标:程序代码空间的程序代码空间的任意位置任意位置正常程序行为正常程序行为call的跳转目标:的跳转目标:函数的首地址函数的首地址ret的跳转目标:的跳转目标:call的下一条指令地址的下一条指令地址ret更加准确的目标:更加准确的目标:对应对应call的下一条指令地址的下一条指令地址jump的跳转目标:的跳转目标:函数的首地址,本函数内部函数的首地址,本函数内部的任意地址的任意地址粗粒度CFI的原理基本思想:基本思想:通过牺牲一部分准确性来降低损耗与实现难度。通过牺牲一部分准确性来降低损耗与实现难度。粗粒度粗粒度CFI(Coarse-Grained CFI),),对代对代码复用攻击和正常程序行为特征进行深入分码复用攻击和正常程序行为特征进行深入分析,通过析,通过特定的规则特定的规则来判断程序行为是否正来判断程序行为是否正常。常。细粒度细粒度CFI(经典(经典CFI)使用使用CFG来判断是否异常来判断是否异常粗粒度粗粒度CFI(启发式(启发式CFI)使用使用特定的规则特定的规则来判断是否异常来判断是否异常粗粒度CFI的规则粗粒度粗粒度CFI使用使用特定的规则特定的规则来判断程序行为是来判断程序行为是否异常:否异常:基于间接跳转指令基于间接跳转指令跳转目标跳转目标的规则的规则以上规则来源于对以上规则来源于对CFG的分析和简化,防御效果严的分析和简化,防御效果严格低于细粒度格低于细粒度CFI,因此被称为粗粒度,因此被称为粗粒度CFI基于基于配件长度配件长度(间接跳转指令频率)的规则(间接跳转指令频率)的规则以上规则来源于对代码复用攻击行为特征的分析以上规则来源于对代码复用攻击行为特征的分析需要设定合适的阈值,存在误判和漏判的可能需要设定合适的阈值,存在误判和漏判的可能也被称为启发式也被称为启发式CFI(heuristic-based CFI)粗粒度CFI的规则基于间接跳转指令基于间接跳转指令跳转目标跳转目标的规则:的规则:ret指令指令1)跳转到)跳转到任意任意call指令的下一条指令指令的下一条指令2)跳转到)跳转到对应对应call指令的下一条指令指令的下一条指令call指令指令跳转到任意函数的首地址跳转到任意函数的首地址jump指令指令跳转到任意函数的首地址,或者当前函数的任意地跳转到任意函数的首地址,或者当前函数的任意地址址粗粒度CFI的规则基于基于配件长度配件长度(间接跳转指令频率)的规则(间接跳转指令频率)的规则配件是以间接跳转指令为结尾的代码片段配件是以间接跳转指令为结尾的代码片段以以间接跳转指令间接跳转指令为边界,将所有处于两个间接为边界,将所有处于两个间接跳转指令之间的代码片段都当做是跳转指令之间的代码片段都当做是潜在的配件潜在的配件粗粒度CFI的规则基于基于配件长度配件长度(间接跳转指令频率)的规则(间接跳转指令频率)的规则配件长度和间接跳转指令的频率是完全等价的配件长度和间接跳转指令的频率是完全等价的配件配件长度越短长度越短,间接跳转指令出现的,间接跳转指令出现的频率越高频率越高配件配件长度越长长度越长,间接跳转指令出现的,间接跳转指令出现的频率越低频率越低粗粒度CFI的规则基于基于配件长度配件长度(间接跳转指令频率)的规则(间接跳转指令频率)的规则为了达成预期攻击目标,避免无用指令的干扰,为了达成预期攻击目标,避免无用指令的干扰,配件链通常由配件链通常由多个短配件多个短配件组成。组成。短配件短配件:配件中的指令数量不大于:配件中的指令数量不大于x配件链配件链:连续出现:连续出现y个短配件个短配件一旦发现连续出现一旦发现连续出现y个长度不大于个长度不大于x的短配件,就认的短配件,就认为发生了代码复用攻击。为发生了代码复用攻击。x,y是是可配置的可配置的。x通常设为通常设为5-6y通常设为通常设为10-20粗粒度CFI的规则基于基于配件长度配件长度(间接跳转指令频率)的规则(间接跳转指令频率)的规则配件!配件!配件!配件!配件!配件!配件!配件!配件!配件!配件出现频率太多,配件出现频率太多,发生攻击!终止进程发生攻击!终止进程监测监测窗口窗口.ins;ins;ins;ins;retret;ins;ins;retret;ins;ins;ins;ins;ins;ins;retret;ins;ins;retret;ins;ins;ins;ins;retret;.粗粒度CFI的实现粗粒度粗粒度CFI规则的具体实现:规则的具体实现:基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现规则的实现对对call、jump、ret指令及其跳转目标的指令及其跳转目标的实时实时监控和监控和分析分析基于基于配件长度配件长度(间接跳转指令频率)规则的实(间接跳转指令频率)规则的实现现对间接跳转指令和普通指令运行数量的对间接跳转指令和普通指令运行数量的实时实时监控和监控和分析分析粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:call的跳转目标地址应该是函数首地址的跳转目标地址应该是函数首地址修改二进制文件,对所有修改二进制文件,对所有函数的首地址函数的首地址加一个标记。加一个标记。程序运行时,检测所有程序运行时,检测所有call指令的跳转目标地址是指令的跳转目标地址是否是否是被标记的函数首地址被标记的函数首地址。如果不是函数首地址,则认为发生了异常。如果不是函数首地址,则认为发生了异常。粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:jump的跳转目标地址应该是函数首地址或者当的跳转目标地址应该是函数首地址或者当前函数内部的任意地址前函数内部的任意地址修改二进制文件,对所有修改二进制文件,对所有函数的首地址函数的首地址加一个标记,加一个标记,并且标记所有并且标记所有函数的长度函数的长度。程序运行时,根据函数首地址和长度,能够判断当程序运行时,根据函数首地址和长度,能够判断当前执行指令处于哪一个函数内部。前执行指令处于哪一个函数内部。粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:jump的跳转目标地址应该是函数首地址或者当的跳转目标地址应该是函数首地址或者当前函数内部的任意地址前函数内部的任意地址检测检测jump指令的跳转目标地址指令的跳转目标地址是否跨越了是否跨越了当前函数当前函数边界。如果没有,继续运行。边界。如果没有,继续运行。如果跨越了当前函数边界,检测如果跨越了当前函数边界,检测jump的跳转目标地的跳转目标地址是否为址是否为被标记的函数首地址被标记的函数首地址。粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:ret的跳转目标地址应该是的跳转目标地址应该是任意任意call指令的下一指令的下一条指令条指令程序运行时,检测程序运行时,检测ret指令的跳转目标地址是否是指令的跳转目标地址是否是call指令的下一条指令。指令的下一条指令。如果不是,则认为发生了异常。如果不是,则认为发生了异常。粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:ret的跳转目标应该是的跳转目标应该是对应对应call的下一条指令的下一条指令ret和和call是是一一对应一一对应的,并且的,并且ret对应的是对应的是最近最近一次一次call。程序运行时,记录程序运行时,记录call指令的下一条指令地址。指令的下一条指令地址。当执行当执行ret指令时,检测指令时,检测ret指令的跳转目标地址是指令的跳转目标地址是否是最近一次否是最近一次call指令的下一条指令。指令的下一条指令。粗粒度CFI的实现基于间接跳转指令基于间接跳转指令跳转目标跳转目标规则的实现:规则的实现:ret的跳转目标应该是的跳转目标应该是对应对应call的下一条指令的下一条指令call指令的作用就是将指令的作用就是将函数返回地址函数返回地址压栈,然后压栈,然后跳转到对应函数执行。跳转到对应函数执行。call指令的下一条指令地址就是函数返回地址。指令的下一条指令地址就是函数返回地址。粗粒度粗粒度CFI对对ret目标地址的检测行为和正常程序目标地址的检测行为和正常程序的函数调用行为是的函数调用行为是相同的相同的。粗粒度CFI的实现影子栈(影子栈(shadow stack),),是独立于用户栈是独立于用户栈的另外一个栈空间,专门用于保存的另外一个栈空间,专门用于保存函数返回函数返回地址地址。影子栈是实现粗粒度影子栈是实现粗粒度CFI对对ret目标地址检测目标地址检测的常用方法。的常用方法。执行执行call指令时,除了将函数返回地址正常压栈指令时,除了将函数返回地址正常压栈以外,同时将函数返回地址压入影子栈。以外,同时将函数返回地址压入影子栈。执行执行ret指令时,同时读取栈和影子栈的两个函指令时,同时读取栈和影子栈的两个函数返回地址,并进行比较。数返回地址,并进行比较。如果两者相等,则正常,继续执行。如果不相如果两者相等,则正常,继续执行。如果不相等,则认为发生了攻击。等,则认为发生了攻击。粗粒度CFI的实现基于基于配件长度配件长度规则的实现:规则的实现:x86处理器中有一个特殊的寄存器处理器中有一个特殊的寄存器LBR(Last Branch Record),用于记录最后,用于记录最后16项跳转指项跳转指令的信息。令的信息。利用利用LBR记录并分析间接跳转指令,配件长度记录并分析间接跳转指令,配件长度等于两个连续间接跳转指令之间指令数量。等于两个连续间接跳转指令之间指令数量。一旦发现连续出现一旦发现连续出现y个长度不大于个长度不大于x的短配件,的短配件,就认为发生了代码复用攻击。就认为发生了代码复用攻击。粗粒度CFI的实现基于基于配件长度配件长度规则的实现:规则的实现:一旦发现连续出现一旦发现连续出现y个长度不大于个长度不大于x的短配件,的短配件,就认为发生了代码复用攻击。就认为发生了代码复用攻击。一个难点在于一个难点在于x和和y的设置,如果设置不好,会的设置,如果设置不好,会导致出现大量的误判或漏判。导致出现大量的误判或漏判。误判误判:将正常程序当做了异常。:将正常程序当做了异常。漏判漏判:将异常程序当做了正常。:将异常程序当做了正常。如果如果x设置过小,可能将真正的配件当做了正常设置过小,可能将真正的配件当做了正常程序(漏判)。如果程序(漏判)。如果x设置过大,可能将正常程设置过大,可能将正常程序当做了配件(误判)。序当做了配件(误判)。y的设置和的设置和x类似。类似。粗粒度CFI的实际应用2016年年Intel提出了提出了CET(Control-flow Enforcement Technology,控制流增强技,控制流增强技术),是粗粒度术),是粗粒度CFI的一种具体实现形式。的一种具体实现形式。实现实现影子栈影子栈,完成对,完成对ret跳转目标的检测。跳转目标的检测。实现对实现对call和和jump跳转目标的检测。跳转目标的检测。增加了一条新的指令增加了一条新的指令ENDBR32/ENDBR64,在所,在所有函数头插入有函数头插入ENDBR32/ENDBR64。call和和jump的跳转目标必须是的跳转目标必须是ENDBR32/ENDBR64。粗粒度CFI和经典CFI的区别经典经典CFI(细粒度(细粒度CFI)需要需要CFG根据根据CFG严格限制间接跳转指令的跳转目标,严格限制间接跳转指令的跳转目标,但是精确的但是精确的CFG难以分析得到难以分析得到粗粒度粗粒度CFI使用使用特定的规则特定的规则根据对代码复用攻击和正常程序行为特征分析,根据对代码复用攻击和正常程序行为特征分析,总结得到一些特定的规则总结得到一些特定的规则粗粒度CFI分析优点:优点:实现简单,效率高,开始被实际系统逐步的采实现简单,效率高,开始被实际系统逐步的采用用能够防御大部分常见的代码复用攻击,提高代能够防御大部分常见的代码复用攻击,提高代码复用攻击的攻击难度码复用攻击的攻击难度限制了间接跳转指令的跳转目标,加大了寻找可用限制了间接跳转指令的跳转目标,加大了寻找可用配件的难度配件的难度限制了配件的长度,加大了构造配件链的难度限制了配件的长度,加大了构造配件链的难度粗粒度CFI分析缺点:缺点:防御效果低于经典的防御效果低于经典的CFI能够被有针对性的绕过能够被有针对性的绕过从学术角度,防御效果仍然是不够从学术角度,防御效果仍然是不够小结本小节介绍了本小节介绍了粗粒度粗粒度CFI,是异常行为检测领,是异常行为检测领域一种高效实用的防御方法。域一种高效实用的防御方法。分析代码复用攻击和正常程序行为特征,总分析代码复用攻击和正常程序行为特征,总结了几个特定的规则:结了几个特定的规则:基于间接跳转指令跳转目标的规则基于间接跳转指令跳转目标的规则基于配件长度(间接跳转指令频率)的规则基于配件长度(间接跳转指令频率)的规则粗粒度粗粒度CFI目的并不在于彻底阻止代码复用攻目的并不在于彻底阻止代码复用攻击,而是要增加攻击者构造配件链的难度。击,而是要增加攻击者构造配件链的难度。主要内容研究背景研究背景粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的代码复用攻击的代码复用攻击COOP和和FOPJIT-ROP不可读保护不可读保护CPI总结总结粗粒度CFI的本质通过一些通过一些特定规则特定规则来判断程序行为是否异常来判断程序行为是否异常ret指令指令1)跳转到)跳转到任意任意call指令的下一条指令指令的下一条指令2)跳转到)跳转到对应对应call指令的下一条指令指令的下一条指令call指令指令跳转到任意函数的首地址跳转到任意函数的首地址jump指令指令跳转到任意函数的首地址,或者当前函数的任意地跳转到任意函数的首地址,或者当前函数的任意地址址配件长度(间接跳转指令频率)配件长度(间接跳转指令频率)连续出现多个短配件连续出现多个短配件绕过粗粒度CFI的方法合法配件合法配件:符合粗粒度:符合粗粒度CFI规则的特殊的配件。规则的特殊的配件。利用合法配件组成配件链,就能够绕过粗粒利用合法配件组成配件链,就能够绕过粗粒度度CFI的防御。的防御。Call-Preceded Gadget,CP配件,符合配件,符合ret指指令跳转目标的规则。令跳转目标的规则。Entry-Point Gadget,EP配件,符合配件,符合call和和jump跳转目标的规则。跳转目标的规则。Long-NOP Gadget,LN配件,符合基于配件配件,符合基于配件长度的规则。长度的规则。CALL-PRECEDED配件ret指令的跳转目标规则:跳转到指令的跳转目标规则:跳转到任意任意call指指令的下一条指令。令的下一条指令。call-preceded指令指令:call指令的下一条指令。指令的下一条指令。call-preceded配件配件:以:以call-preceded指令指令为起始的配件。为起始的配件。call-preceded配件符合上述对于配件符合上述对于ret指令的指令的规则。规则。注:注:call-preceded配件不符合更加精确的配件不符合更加精确的ret跳跳转目标的规则:跳转到转目标的规则:跳转到对应对应call指令的下一条指指令的下一条指令。令。CALL-PRECEDED配件程序中程序中call指令的数量很多,研究表明能够指令的数量很多,研究表明能够找到许多找到许多call-preceded配件,足够满足攻击配件,足够满足攻击者所需要的功能。者所需要的功能。由由call-preceded配件组成的配件链能够绕过配件组成的配件链能够绕过对对ret返回地址的检测。返回地址的检测。ENTRY-POINT配件call和和jump的跳转目标规则:的跳转目标规则:call和和jump应应该跳转到函数的首地址。该跳转到函数的首地址。entry-point配件配件:以函数首地址为起始的配:以函数首地址为起始的配件。件。entry-point配件符合上述对于配件符合上述对于call和和jump指指令的规则。令的规则。ENTRY-POINT配件程序中函数数量很多,研究表明能够找到许程序中函数数量很多,研究表明能够找到许多多entry-point配件,足够满足攻击者所需要配件,足够满足攻击者所需要的功能。的功能。使用使用entry-point配件组成的配件链就能绕过配件组成的配件链就能绕过针对针对call和和jump跳转地址的检测。跳转地址的检测。LONG-NOP配件基于配件长度的规则:不能连续出现多个短基于配件长度的规则:不能连续出现多个短配件。配件。显然,在配件链中插入一些长配件就能绕过显然,在配件链中插入一些长配件就能绕过上述规则。上述规则。但是,长度越长的配件,指令越多,行为更但是,长度越长的配件,指令越多,行为更加复杂,会影响配件链的稳定性和功能。加复杂,会影响配件链的稳定性和功能。Long-NOP配件配件:长度超过阈值:长度超过阈值x的配件,并的配件,并且不影响配件链中有效数据的交互。且不影响配件链中有效数据的交互。LONG-NOP配件Long-NOP配件配件:不能对正常配件之间的数:不能对正常配件之间的数据交互产生影响。配件之间的数据交互是通据交互产生影响。配件之间的数据交互是通过寄存器完成的。过寄存器完成的。因此,因此,LN配件应该包含以下指令:配件应该包含以下指令:1)包含一些如)包含一些如NOP指令等不修改寄存器的指令。指令等不修改寄存器的指令。2)包含一些写内存指令。可以控制这些指令的)包含一些写内存指令。可以控制这些指令的目标地址,让这些写内存指令去修改无关紧要目标地址,让这些写内存指令去修改无关紧要的内存内容,而不会影响配件链的正常功能。的内存内容,而不会影响配件链的正常功能。.ins;ins;ins;ins;retret;ins;ins;retret;ins;ins;retret;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;ins;retret;ins;ins;retret;ins;ins;ins;ins;retret;.配件!配件!配件!配件!配件出现的频率配件出现的频率不够高不够高,没有发,没有发生生攻击。攻击。非配非配件件监测监测窗口窗口攻击者插入的没有实攻击者插入的没有实际作用的长配件,其际作用的长配件,其长度超过了被认作配长度超过了被认作配件的要求。稀释了配件的要求。稀释了配件出现的频率,逃过件出现的频率,逃过监测监测。LONG-NOP配件Long-NOP配件配件的使用。的使用。Long-NOP配件配件不能影响配件链不能影响配件链的攻击功能。的攻击功能。配件!配件!配件!配件!配件!配件!小结针对粗粒度针对粗粒度CFI的规则,采用特殊的的规则,采用特殊的合法配件合法配件,伪装成正常的程序。伪装成正常的程序。Call-Preceded Gadget,CP配件,符合配件,符合ret指指令跳转目标的规则。令跳转目标的规则。Entry-Point Gadget,EP配件,符合配件,符合call和和jump跳转目标的规则。跳转目标的规则。Long-NOP Gadget,LN配件,符合基于配件配件,符合基于配件长度的规则。长度的规则。以上三种配件可以混合使用,相互配合,共以上三种配件可以混合使用,相互配合,共同绕过粗粒度同绕过粗粒度CFI的防御。的防御。主要内容研究背景研究背景粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的代码复用攻击的代码复用攻击COOP和和FOPJIT-ROP不可读保护不可读保护CPI总结总结粗粒度CFI的分析根据前两节的内容,可以发现粗粒度根据前两节的内容,可以发现粗粒度CFI的规则主的规则主要是围绕要是围绕函数函数开展的。开展的。因此,如果以因此,如果以函数函数为配件,几乎符合所有粗粒度为配件,几乎符合所有粗粒度CFI的规则:的规则:符合精确的符合精确的ret跳转目标规则:跳转到跳转目标规则:跳转到对应对应call指令的下一条指令。指令的下一条指令。符合符合call和和jump的跳转目标规则:跳转到任意的跳转目标规则:跳转到任意函数的首地址。函数的首地址。符合配件长度规则:函数的长度一般要大于符合配件长度规则:函数的长度一般要大于5-6条指令。条指令。COOP的原理COOP(Counterfeit Object-Counterfeit Object-Oriented riented ProgrammingProgramming,面向伪造对象的编程方法),面向伪造对象的编程方法)是是2015年提出的一种新的代码复用攻击方法。年提出的一种新的代码复用攻击方法。针对针对C+C+编程语言,编程语言,COOP攻击攻击通过建立虚假对通过建立虚假对象,用已经存在的象,用已经存在的C+C+虚函数虚函数为配件来构造配件为配件来构造配件链。链。FOP的原理FOP(Function-oriented programming,面向函数的编程方法)面向函数的编程方法)目前还没有类似的工作,是我参考目前还没有类似的工作,是我参考COOP的特的特点,提出的针对点,提出的针对C语言的代码复用攻击方法。语言的代码复用攻击方法。简单来说,就是利用程序中已经存在的简单来说,就是利用程序中已经存在的函数函数为为配件,构造配件链进行攻击。配件,构造配件链进行攻击。COOP攻击:攻击:以以虚函数虚函数为配件,针对为配件,针对C+语言语言FOP攻击:攻击:以以函数函数为配件,针对为配件,针对C语言语言FOP的配件FOP的实现和的实现和JOP类似,将配件分为两种类类似,将配件分为两种类型:型:功能配件功能配件(functional gadget)完成某种特定功能的函数配件。完成某种特定功能的函数配件。调度配件调度配件(dispatcher gadget)充当程序充当程序EIP的作用,实现控制流的转移。的作用,实现控制流的转移。负责组织功能配件的执行。负责组织功能配件的执行。FOP的攻击过程初始化初始化FOP攻击,注入攻击数据。攻击,注入攻击数据。控制调度配件的函数指针,跳转到功能配件。控制调度配件的函数指针,跳转到功能配件。功能配件执行完成,返回到调度配件。功能配件执行完成,返回到调度配件。调度配件继续,跳转到下一个功能配件。调度配件继续,跳转到下一个功能配件。一直循环,完成一直循环,完成FOP攻击。攻击。FOP的功能配件FOP的功能配件举例:的功能配件举例:读写内存的配件读写内存的配件运算配件运算配件FOP的功能配件FOP的功能配件举例:的功能配件举例:条件分支配件条件分支配件FOP的功能配件FOP的功能配件举例:的功能配件举例:读寄存器的配件读寄存器的配件FOP的功能配件FOP的功能配件举例:的功能配件举例:写寄存器的配件写寄存器的配件FOP的调度配件FOP的调度配件的调度配件内部包含内部包含函数指针函数指针,并且尽量不要携带参,并且尽量不要携带参数。数。三种常见调度配件:三种常见调度配件:1)循环,一个函数指针,一个能够修)循环,一个函数指针,一个能够修改函数指针的内存漏洞改函数指针的内存漏洞FOP的调度配件FOP的调度配件的调度配件三种常见调度配件:三种常见调度配件:2)两个不同的函数指针,一个能够修)两个不同的函数指针,一个能够修改这两个函数指针的内存漏洞改这两个函数指针的内存漏洞FOP的调度配件FOP的调度配件的调度配件三种常见调度配件:三种常见调度配件:3)循环,一个二级函数指针)循环,一个二级函数指针COOP和FOP的分析优点:优点:函数是程序的基本功能单元,通常具有一个固函数是程序的基本功能单元,通常具有一个固定的功能,而且函数在程序中数量很多,因此定的功能,而且函数在程序中数量很多,因此能够很方便的构造出以函数为配件的能够很方便的构造出以函数为配件的COOP和和FOP。COOP和和FOP都是图灵完备的攻击。都是图灵完备的攻击。函数配件包含较多的指令,长度一般较长,能函数配件包含较多的指令,长度一般较长,能够绕过以配件长度为判断规则的粗粒度够绕过以配件长度为判断规则的粗粒度CFI。COOP和FOP的分析优点:优点:以函数为配件,相当于结合了以函数为配件,相当于结合了call-preceded和和entry-point两种配件的特征,符合粗粒度两种配件的特征,符合粗粒度CFI对对ret、call、jump的跳转目标的规则,因此的跳转目标的规则,因此COOP和和FOP都能够绕过粗粒度都能够绕过粗粒度CFI。函数指针是动态数据,在程序运行时实时赋值函数指针是动态数据,在程序运行时实时赋值和变化,静态分析难以获取函数指针的具体信和变化,静态分析难以获取函数指针的具体信息,静态分析得到的息,静态分析得到的CFG也难以限制函数指针也难以限制函数指针的跳转,因此的跳转,因此COOP和和FOP也能绕过不够精确也能绕过不够精确的细粒度的细粒度CFI。FOP的攻击示例环境:环境:Ubuntu 16.04,64位位假设条件:假设条件:已知程序的内存布局已知程序的内存布局存在一个可以对内存任意写的漏洞存在一个可以对内存任意写的漏洞本次攻击目的本次攻击目的执行执行system(“/bin/sh”)FOP的攻击示例FOP的攻击示例小结介绍了介绍了COOP和和FOP,以函数为配件,构造,以函数为配件,构造配件链进行攻击。配件链进行攻击。COOP和和FOP易于构造,能够绕过粗粒度易于构造,能够绕过粗粒度CFI,是一种比较优秀的代码复用攻击方法。,是一种比较优秀的代码复用攻击方法。主要内容研究背景研究背景粗粒度粗粒度CFI绕过粗粒度绕过粗粒度CFI的代码复用攻击的代码复用攻击COOP和和FOPJIT-ROP不可读保护不可读保护CPI总结总结随机化防御方法ASLR:对堆、栈、共享库映射等线性内存:对堆、栈、共享库映射等线性内存区域布局进行随机化。区域布局进行随机化。ASLR随机化的粒度很随机化的粒度很粗,同一个内存段中粗,同一个内存段中内部相对偏移是固定的内部相对偏移是固定的。如果攻击者知道了一条指令的位置,就能够根如果攻击者知道了一条指令的位置,就能够根据相对偏移,找到其他指令的地址。据相对偏移,找到其他指令的地址。细粒度细粒度随机化防御:提高内存空间随机化的随机化防御:提高内存空间随机化的粒度,以粒度,以页面、程序块甚至单条指令为单位页面、程序块甚至单条指令为单位进行内存位置随机化,能够进一步提高攻击进行内存位置随机化,能够进一步提高攻击者获取配件的难度,提升系统的安全性。者获取配件的难度,提升系统的安全性。随机化防御方法随机化防御的实现:随机化防御的实现:在程序的装载阶段,操作系统将程序的每个模在程序的装载阶段,操作系统将程序的每个模块块(例如代码段、数据段、栈、堆、代码块、单例如代码段、数据段、栈、堆、代码块、单条指令等条指令等)的基地址进行随机化排布。的基地址进行随机化排布。攻击者无法准确获得某个配件的精确地址,因攻击者无法准确获得某个配件的精确地址,因此无法构造配件链进行攻击。此无法构造配件链进行攻击。潜在问题潜在问题:只在程序加载过程进行随机化,之:只在程序加载过程进行随机化,之后的程序运行过程,内存布局保持不变。后的程序运行过程,内存布局保持不变。内存信息泄露内存信息泄露内存信息泄露是随机化防御面临的最大难题:是随机化防御面临的最大难题:直接泄露:读取代码段,找到直接跳转和直接直接泄露:读取代码段,找到直接跳转和直接调用的目标地址,收集这些地址进行分析,就调用的目标地址,收集这些地址进行分析,就可以得出代码页的分布位置。可以得出代码页的分布位置。间接泄露:读取数据段中的函数指针,虚表以间接泄露:读取数据段中的函数指针,虚表以及栈中返回地址等包含代码地址的数据,可以及栈中返回地址等包含代码地址的数据,可以达到相同的效果。达到相同的效果。由于随机化只在加载过程进行,攻击者可以由于随机化只在加载过程进行,攻击者可以利用内存信息泄露漏洞在程序运行阶段获取利用内存信息泄露漏洞在程序运行阶段获取整个内存空间的信息。整个内存空间的信息。内存信息泄露+代码复用攻击动态内存泄露与代码复用攻击结合,能够绕动态内存泄露与代码复用攻击结合,能够绕过现行大多数商用操作系统的防御机制。过现行大多数商用操作系统的防御机制。攻击者利用内存信息泄露漏洞,结合对目标程攻击者利用内存信息泄露漏洞,结合对目标程序的预先了解,序的预先了解,对运行中的程序内存进行动态对运行中的程序内存进行动态读取,读取,可以获取随机化后的内存布局,从而破可以获取随机化后的内存布局,从而破解了随机化防御方法。解了随机化防御方法。由于程序运行过程中的内存布局保持不变,攻由于程序运行过程中的内存布局保持不变,攻击者能够找到所需配件的精确内存位置,动态击者能够找到所需配件的精确内存位置,动态构造配件链进行攻击。构造配件链进行攻击。JIT-ROP原理JIT-ROP(Just-in-time code reuse),是),是于于2013年提出的一种代码复用攻击方法。年提出的一种代码复用攻击方法。通过实施一连串的内存信息泄露攻击,绕过内通过实施一连串的内存信息泄露攻击,绕过内存位置随机化防御机制,迭代搜索内存空间,存位置随机化防御机制,迭代搜索内存空间,动态查找构造攻击所需的配件位置。动态查找构造攻击所需的配件位置。可以实现自动化的可以实现自动化的ROP攻击,无需攻击者手工攻击,无需攻击者手工查找构造查找构造ROP配件链。配件链。JIT-ROP攻击JIT-ROP攻击的两个前提条件:攻击的两个前提条件:1)需要给攻击框架的接口提供一个内存泄露漏)需要给攻击框架的接口提供一个内存泄露漏洞,以获得某个内存绝对地址中存储的值。洞,以获得某个内存绝对地址中存储的值。2)需要有一个可篡改的代码指针。例如,位于)需要有一个可篡改的代码指针。例如,位于堆上的虚函数指针,或位于栈上的局部变量。堆上的虚函数指针,或位于栈上的局部变量。JIT-ROP攻击步骤JIT-ROP攻击步骤:攻击步骤:1)获取一个代码页:)获取一个代码页:向向JIT-ROP攻击框架接口提供一个内存泄露漏洞和攻击框架接口提供一个内存泄露漏洞和一个初始代码指针。通过对该代码指针所指位置的一个初始代码指针。通过对该代码指针所指位置的反复读取,获取到整个反复读取,获取到整个4KB大小的代码页。大小的代码页。JIT-ROP攻击步骤JIT-ROP攻击步骤:攻击步骤:2)获取多个代码页:)获取多个代码页:实行动态代码分析技术来确认初始代码页中的间接实行动态代码分析技术来确认初始代码页中的间接和直接转移指令(和直接转移指令(jmp和和call),利用这些跳转指令),利用这些跳转指令的目标地址来寻找其他代码页。的目标地址来寻找其他代码页。如果发现某个跳转指令的目标地址不在同一个页内,如果发现某个跳转指令的目标地址不在同一个页内,则说明该目标地址对应的指令存于另外一个新的代则说明该目标地址对应的指令存于另外一个新的代码页。码页。不断进行以上操作,直到找到足够数量的代码页。不断进行以上操作,直到找到足够数量的代码页。JIT-ROP攻击步骤JIT-ROP攻击步骤:攻击步骤:3)查找)查找API函数:函数:根据根据API函数调用操作序列的特征在第二步中找到函数调用操作序列的特征在第二步中找到的所有代码页中查找,寻找能够调用的所有代码页中查找,寻找能够调用API函数的配件函数的配件(如(如call api_func)。)。然后,寻找能够向然后,寻找能够向API函数传递参数的配件。函数传递参数的配件。4)查找配件地址:)查找配件地址:根据配件的功能,动态地在第二步中得到的代码页根据配件的功能,动态地在第二步中得到的代码页中查找可用配件的地址。中查找可用配件的地址。JIT-ROP攻击步骤JIT-R
展开阅读全文