20199123 2019-2020-2 《网络攻防实践》第10周作业

20199123 2019-2020-2 《网络攻防实践》第10周作业

0 总体结构

本次作业属于那个课程 《网络攻防实践》
这个作业要求在哪里 《网络攻防实践》第十周作业
我在这个课程的目标是 学习网络攻防相关技术、掌握网络攻防相关能力
这个作业在哪个具体方面帮助我实现目标 学习软件安全攻防中的缓冲区溢出和Shellcode
作业正文 下述正文
其他参考文献 见文末

1.实践内容

本章知识整体结构图

1.1 软件安全概述

  • 安全漏洞的类型:

    • 缓冲区溢出(最基本的漏洞攻击)
    • 格式化字符串漏洞(主要是C语言中的调用print函数进行输出的时候参数使用不当出现的漏洞)
    • 竞争条件漏洞(多个进程访问同一资源时产生的时间或者序列的冲突)
    • 整数溢出(超过数据类型能够表示的数据范围)
    • XSS跨站脚本(主要是针对Web网页的一种漏洞攻击)
    • SQL注入(漏洞出现的主要原因是程序员在开发用户和数据库交互的系统时没有对用户输入的字符串进行过滤、转义,限制或处理不严谨导致用户可以通过输入精心构造的字符串去非法获取数据库中的数据)
  • 针对安全漏洞的渗透利用技术:

    • 堆溢出
    • 内核溢出
    • 对抗DEP(数据执行保护)机制的ret2libc攻击
    • 对抗ASLR(地址空间布局随机化)机制的Heap Spraying攻击
    • 同时对抗DEP和ASLR的JIT Spraying攻击
  • 安全漏洞定义:在系统安全流程、设计、实现或内部空间中所存在的缺陷或弱点,能够被攻击者所利用并导致安全侵害或对系统安全策略的违反(!!!三个基本要素:系统的脆弱性或缺陷、攻击者对缺陷的可访问性,以及攻击者对缺陷的可利用性)

  • 软件安全“困境三要素”:

    • 复杂性(Complexity):源代码行数(LOC)是目前衡量软件规模的一个重要度量指标;
    • 可扩展性(Extensibility)
    • 连通性(Connectivity):高度的连通性使得一个小小的软件缺陷就很有可能影响非常大的范围;
  • 软件安全漏洞类型从技术上进行分类:

    • 内存安全违规类(Memory Safety Violations):

      ①软件开发过程中处理RAM内存访问时所引入的安全缺陷;②如缓冲区溢出和Double Free(两次调用有同样参数的free())、Use-after-Free(释放后重用,继续使用已经释放的堆内存指针,此错误可能导致任意代码执行)等不安全指针问题等;

      ③主要出现在C/C++等编程语言所编写的软件程序中,由于该类语言支持任意的内存分配与归还、任意的指针计算、转换,而没有进行保护因此非常容易引入漏洞;

      不安全指针是指在计算机程序中存在的并没有指向适当类型对象的非法指针;

    • 输入验证类(Input Validation Errors):

      ①指软件程序在对用户输入进行数据验证存在的错误没有保证输入数据的正确性、合法性和安全性,从而导致可能被恶意攻击与利用;

      ②输入验证类安全漏洞根据输入位置、恶意位置内容被软件程序的使用方式的不同,又包括格式化字符串、SQL注入、代码注入、远程文件包含目录遍历XSSHTTP Header注入HTTP响应分割错误

      远程文件包含(服务器通过PHP的函数去包含任意文件时,由于要包含的文件来源过滤不严,从而可以包含 恶意文件)

      目录遍历(Web应用程序有对服务器文件读取查看的功能,在文件交互过程中,服务器支持特殊符号的目录因此攻击者可以越权访问或者覆盖敏感数据)

      XSS(跨站点脚本,通过利用网页开发留下的漏洞加上巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序)

      HTTP Header注入(后台开发人员为了验证客户端头信息,比如常用的cookie验证或者通过http header头信息获取客户端的一些资料,比如useragent、accept字段等。会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于http header的SQL Inject漏洞)

      HTTP响应分割错误(本质是,攻击者可以发送1个或多个HTTP指令迫使漏洞服务器产生一个攻击者构想好的输出)等多种安全漏洞技术形式;

    • 竞争条件类(Race Conditions Errors):是系统或进程中一类比较特殊的错误,通常涉及多进程或多线程处理的程序中出现,是指处理进程的输出或者结果无法预测,并依赖于其他进行进程实践发生的次序或实践时,所导致的错误

    • 权限混淆与提升类(Privilege confusion and escalation bugs):是指计算机程序由于自身编程疏忽或被第三方欺骗,从而滥用其权限,或赋予第三方不该给予的权限;权限混淆与提升类漏洞的具体技术形式主要有:Web应用程序中的跨站请求伪造(Cross-Site Request Forgery,CSRF)、Clickjacking、FTP反弹攻击、权限提升、“越狱”(jailbreak)等;


1.2 缓冲区溢出基础概念

  • 缓冲区溢出基础概念:在计算机程序向特定缓冲区内填充数据时,超出了缓冲区本身的容量,导致外溢数据覆盖了相邻内存空间的合法数据,从而改变程序执行流程破坏系统运行完整性;

  • 缓冲区溢出攻击根本原因:现代计算机系统的基础架构——冯诺依曼体系存在本质的安全缺陷,即采用了“存储程序”的原理,计算机程序的数据和指令都在同一内存中进行存储,而没有严格的分离,导致攻击者将输入的数据覆盖修改程序在内存空间中与数据区相邻存储的关键指令,从而达到使程序执行恶意注入指令的攻击目的;

  • IA32架构中段寄存器为16位,控制寄存器用来控制处理器的执行流程,其中最关键的是eip,也被称为“指令指针”,它保存了下一条即将执行的机器指令的地址,因而也成为各种攻击控制程序执行流程的关键攻击目标对象;

    寄存器名 说明 功能
    eax 累加器 加法乘法指令的缺省寄存器,函数返回值
    ecx 计数器 REP&LOOP指令的内定计数器
    edx 除法寄存器 存放整数除法产生的余数
    Ebx 基址寄存器 在内存寻址时存放基地址
    esp 栈顶指针寄存器 SS:ESP当前堆栈的栈顶指针
    ebp 栈底指针寄存器 SS:EBP当前堆栈的栈底指针
    esi,dei 源、目的索引寄存器 在字符串操作指令中,DS:ESI指向源串ES:EDI指向目标串
    eip 指令寄存器 CS:EIP指向下一条指令的地址
    eflags 标志寄存器 标志寄存器
    cs 代码段寄存器 当前执行的代码段
    ss 堆栈段寄存器 stack segment当前堆栈段
    ds 数据段寄存器 data segment当前数据段
  • 在IA32架构汇编语言中,又分为Intel和AT&T两种具有很多差异的汇编格式

  • Linux平台与Windows平台进程内存空间分布的对比

  • 进程内存管理:

    • Linux中程序一般包含.text、.bss和.data三种类型的段,.text段包含程序指令,在内存中被映射为只读,.data段主要包含静态初始化的数据,而.bss段则主要包含未经初始化的数据;两者都被映射至可写的内存空间中;

    • 栈是一种后进先出的数据结构,其地址空间从高地址向低地址空间增长,Linux程序运行的环境变量env、运行参数argv、运行参数数量argc都被放置在“栈”底,然后是主函数及调用“栈”中各个函数的临时保存信息;堆是一种先进先出的数据结构,用于保存程序动态分配的数据和变量,其地址空间从低地址向高地址增长;

    • 程序执行时,会按照程序逻辑执行.text中的指令,并在“堆”和“栈”中保存和读取数据,然而程序并不能正确地区分指令和数据,所以当我们通过修改内存空间中影响程序执行逻辑的敏感位置,并将恶意数据作为指令提交给处理器时,它仍会很高兴的执行这些“指令”;

  • 函数调用过程:

    • 栈溢出攻击就是针对函数调用过程中返冋地址在栈中的存储位置,进行缓冲区溢出,从而改写返回地址,达到让处理器指令寄存器跳转至攻击者指定位置执行恶意代码的目的

    • 程序进行函数调用过程三个步骤:

      调用(call):调用者将函数调用参数、函数调用下一条指令的返回地址压栈,并跳转至被调用函数入口地址;

      序言(prologue):被调用函数开始执行首先会进 入序言阶段,将对调用函数的栈基址进行压栈保存,并创建自身函数的栈结构,具体包括将ebp寄存器赋值为当前栈基址,为本地函数局部变量分配栈地址空间,更新esp寄存器为当前栈顶指针等;

      返回(return):被调用函数执行完功能将指令控制权返回给调用者之前,会进行返回阶段的操作,通常执行leave和ret指令,即恢复调用者的栈顶与栈底指针,并 将之前压栈的返回地址装载至指令寄存器eip中,继续执 行调用者在函数调用之后的下一条指令;

    • 函数调用过程代码实例:

  • 缓冲区溢出攻击原理:

    • 缓冲区溢出漏洞根据缓冲区在进程内存空间中的位置不同,又分为栈溢出、堆溢出和内核溢出这三种具体技术形态;

    • 栈溢出安全漏洞实例分析:

      ①代码中的return_input()函数中定义了一个局部变量array,为30字节长度字符串缓冲区;

      ②函数局部变量将被存储在栈上,并位于main()函数调用时压栈的下一条指令(即"return 0;")返回地址之下;

      ③在return_input()函数中执行gets函数将用户终端输入至array缓冲区时,没有进行缓冲区边界检查和保护;

      ④因此如果用户输入超出30字节的字符串时,输入数据将会溢出 array缓冲区,从而覆盖array缓冲区上方的EBP和RET;

      ⑤—旦覆盖了RET返回地址之后,在return_input()函数执行完毕返回main()函数时,EIP寄存器将会装载栈中RET位置保存的值,此时该位置已经被溢出改写为”AAAA“(即0x41414141),而该地址可能是进程无法读取的空间,所以造成程序的段错误("Segmentation fault")

    • 黑客为了通过溢出获得目标程序或系统的访问控制权,需要精心构造缓冲区溢出攻击,解决如下三个挑战:

      ①如何找出缓冲区溢出要覆盖和修改的敏感位置?如栈溢出中的RET返回地址在栈 中的存储位置;

      将敏感位置的值修改成什么?为了完成程序执行流程控制权的转移,攻击者需要将影响程序执行流程敏感位置中的值进行修改,使其能够跳转至攻击者预期的代码进行执行;

      执行什么代码指令来达到攻击目的?在程序控制权移交至攻击者注入的指令后,那么这段指令完成何种功能,如何编写?这段代码被称为攻击的payload,通常会为攻击者给出一个远程的Shell访问,因此也被称为Shellcode;

    • 案例分析:在这个示例代码中,溢出攻击的第一个关键问题一一定位需要修改的敏感位置,即栈中的返回地址,根据对栈结构与内存布局,我们可以定位返冋地址位于要溢出的buffer变量的高地址位置,具体的偏移量与平台相关,但不会超出示例代码中设置的32字节,因而 large_string将除Shellcode外的所有字节均填充为跳转地址,肯定会覆盖到栈中的RET。第二个关键问题——将敏感位置的值修改为什么,示例代码中将其改写为直接指向Shellcode 的地址。第三个关键问题——执行什么代码,示例代码中包含了一段最简单的24字节长度的Shellcode,用于开启一个命令行Shell,因此这段简单的示例代码中解决了溢出攻击的三个关键问题,成功地溢岀了 buffer缓冲区,在运行结果中可以看到程序执行最终开启了一个命令行Shell,并在用户退出这个Shell时正常退出程序,没有造成任何异常朋溃的情况;


1.3 Linux平台上的栈溢出

  • Linux平台栈溢出攻击按照攻击数据的构造方式不同,主要有NSR、RNS和RS三种;

    • NSR模式:适用于被溢出缓冲区变量比较大,足以容纳Shellcode的情况,其攻击数据从低地址到高地址的构造方式是一堆Nop指令(即空指令)之后填充Shellcode,再加上一些期望覆盖RET返回地址的跳转地址从而构成了NSR攻击数据缓冲区;

    • RNS模式:一般用于被溢出的变量比较小,不足以容纳Shellcode的情况,攻击数据从低地址到高地址的构造方式是首先填充一些期望覆盖RET返回地址的跳转地址,然后是一堆Nop指令填充“着陆区”,最后再是 Shellcode。在溢出攻击之后,攻击数据将在RET区段即溢出了目标漏洞程序的小缓冲区, 并覆盖了栈中的返回地址,然后跳转至Nop指令所构成的“着陆区”,并最终执行Shellcode;

    • RS模式:在这种模式下能够精确地定位出Shellcode在目标漏洞程序进程空间中的起始地址,因此也就无须引入Nop 空指令构建“着陆区”。这种模式是将Shellcode放置在目标漏洞程序执行时的环境变量中, 由于环境变量是位于Linux进程空间的栈底位置,因而不会受到各种变量内存分配与对齐因素的影响,其位置是固定的;

    • 本地栈溢出的用户输入传递途径主要为argv命令行输入、文件输入等,而远程栈溢出的用户输入传递途径则是通过网络,存在远程栈溢出漏洞的往往是一些网络服务进程或网络应用程序,攻击者可以在网络应用层协议交互过程中,利用上述介绍的模式构造恶意网络数据包,发送给漏洞程序,从而进行渗透攻击。NSR和RNS模式也都适用于远程栈溢出攻击,使用场景也主要取决于被溢出的目标缓冲区大小是否足够容纳Shellcode。由于RS 模式是通过本地的execve()将Shellcode放置在环境变量中传递给目标漏洞程序,因此这种模式不适用于通过网络的远程缓冲区溢出攻击,而只能用于本地缓冲区溢出攻击


    • Linux本地Shellcode实现机制:

      ①通过execve()函数启动/bin/sh提供命令行;

      ②分别将execve()函数的参数NULL(0x0)、name变量地址、"/bin/sh"字符串地址压入栈中,然后将eax赋值为execve()系统调用号0xb,执行int 0x80软中断,即调用了 cxecve()函数,;并将压栈的输入参数传递给execve()函数例程,从而完成开启Shell 的功能

      ③右侧代码在左侧汇编代码中引入二进制指令空字节(即0x00或NULL)进行消除,进行空字节的消除处理是为了使得最终编制的Shellcode 中不存在空字节,从而避免在渗透攻击中对strcpy()等字符串操作函数时,在空字节处截断 Shcllcode致使攻击失效;

      ④然后通过查找Intel opcode指令参数手册对汇编代码进行编译和调试,即可获得opcode二进制指令形式的Shellcode,将这些opcode二进制指令代码连接再一起,并保存在攻击数据缓冲区中;

      ⑤往往还会在运行execve()启动shell之前,调用setreuid(0) 将程序运行权限提升至Root用户(需要该程序所有者为Root,旦被设置了 SUID位),这 样才能利用木地溢出攻击来提升权限,在执行execve()函数之后还需执行exit。函数,从而 在溢出攻击之后能够使程序正常退出。

    • Linux远程Shellcode实现机制:和本地Shellcode实现机制的步骤一致,不同点为:

      ①Linux远程Shellcode需要让攻击目标程序创建socket监听指定的端口等待客户端连接, 启动一个命令行Shell,并将命令行的输入输出与socket绑定,这样攻击者就可以通过socket 客户端连接目标程序所在主机的开放端口,与服务端socket建立起通信通道,并获得远程访问Shell;

      ②在Linux系统中,dup2()函数能够将标准输入输岀与socket的网络通信通道进行绑定,使得socket的远程输入连接至命令行标准输入,将命令行标准输出连接至远程网络输出,因而完成远程Shell的功能;

      ③远程Shellcode实现还需要考虑远程Shell能够渗透防火墙,以及如何使得远程Shellcode支持上传和下载文件等额外功能;


1.4 Windows平台上的栈溢出与Shellcode

  • Windows平台和Linux平台具有显著不同的实现机制,而在这些差异中,与成功攻击应用程序中栈溢出漏洞密切相关的主要有如下三点:

    ①对程序运行过程中废弃栈的处理方式差异;Windows平台会向废弃栈中写入一些随机的数据,而Linux则不 进行任何的处理。这点差异导致了实施栈溢出攻击时,Windows平台中构建攻击缓冲区数据在栈中植入恶意指令时,会而临一些限制;

    进程内存空间的布局差异;Linux进程内存空间中栈底指针在0xc0000000之下,即一般栈中变量的位置都在Oxbfff地址附近,在这些地址中没有空字行。Windows平台的栈位置处于0x00FFFFFF以下的用户内存空间,—般为 0x0012地址附近,而这些内存地址的首字节均为0x00空字节;

    系统功能调用的实现方式差异;Linux系统中通过“int 80”中断处理来调用系统功能,而Windows系统则是通过操作系统中更为复杂的API及内核处理例程调用链来完成系统功能调用,対应用程序直接可见的是应用层中如 Kernel32.dll、User32.dll等系统动态链接库中导出的一些系统API接口函数;

  • 远程栈溢出攻击示例:

    这是一个非常简单的字符串接收与回显服务端程序,通过Windows Socket机制创建一个服务器端Socket,在TCP3764端口监听,在接受客户端连接之后,把客户端输入的字符串统计接收 字节数,并进行回显,但在调用overflow()函数中将接收字符串复制至本地局部变量s1缓冲区时,没有进行边界保护,因此存在着栈溢出安全漏洞;

    上图是针对漏洞服务程序的一个远程渗透攻击程序,攻击过程也非常简单明了;

    ①即首先创建一个客户端socket,并连接目标漏洞服务程序所监听的IP地址与端口

    ②然后精心组装一个用于溢出目标程序缓冲区的攻击数据,这是整个攻击过程中最为关键的步骤

    ③通过对代码的细致分析,我们可以看到攻击数据缓冲区Buff是一个1024字节长度的字符数组,首先填充了一段Nop指令(事实上也可以用其他字符填充);

    ④然后在事先计算好的返回地址位置放置了一个指向“JMP ESP”指令的地址,而该指令地址在不同的目标程序运行系统上是不一样的,是由攻击者通过在各个系统环境中调试获得;

    ⑤在示例代码中,我们针对Windows XP系统版本,并从user32.dll或ws2_32.dll中查找到“JMP ESP”指令的地址, 分别为0x776418fc和0x71a27bfb;

    ⑥然后再往攻击数据缓冲区中加载一段Windows平台的远程Shellcode

    ⑦最后调用send()函数将攻击数据通过socket发给目标服务,即可渗透攻击日标服务程序获得远程访问权;

  • 野外Windows栈溢出代码在互联网上随处可得,在Exploit-db、Milw0rm、Packetstorm等渗透攻击代码共享网站上,有些甚至还能找到尚未发布补丁的“零日”漏洞;


  • Windows平台Shellcode实现技术

    • 需要考虑的问题:

      ①Shellcode必须可以找到所需的Windows 32 API函数,井生成函数调用表

      ②为了能够使用这些API函数,Shellcode必须找出目标程序已加载的函数地址,或者需自行加载所需函数库,获得所需函数在目标程序进程内存空间中的加截地址,并获得它们在目标程序进程内存空间的加载地址;

      ③Shellcode需考虑消除空字节,以避免在字符串操作函数中被截断,如果目标程序有更进一步的过滤规则,那么Shellcode在编写时需添加一些编码机制,以顺利通过过滤器;

      ④Shellcode需确保自己可以正常退出,并使原来的目标程序进程继续运行或终止;

      ⑤在目标系统环境存在异常处理和安全防护机制时,Shellcode需进一步考虑如何对抗这些机制

    • Windows本地Shellcode实例分析:

      #include <windows.h>
      #include <winbase.h>
      typedef void (*MYPROC)(LPTSTR);
      typedef void (*MYPROC2)(int);
      int main()
      {
      	HINSTANCE LibHandle;
      	MYPROC ProcAdd;
      	MYPROC2 ProcAdd2;
      	char dllbuf[11] = "msvcrt.dll";
      	char sysbuf[7] = "system";
      	char cmdbuf[16] = "command.com";
      	char sysbuff2[5] = "exit";
      	LibHandle = LoadLibrary(dllbuf);
      	ProcAdd = (MYPROC)GetProcAddress(LibHandle,sysbuf);
      	(ProcAdd) (cmdbuf);
      	ProcAdd2 = (MYPROC2)GetProcAddress(LibHandle,sysbuf2);
      	(ProcAdd2) (0);
      }
      

      ①使用LoadLibrary()函数加载msvcrt.dll动态链接库,并通过GetProcAddress()函数获得system函数的加载入口地址,赋值给ProcAdd函数指针;

      ②然后通过函数指针调用system()函数,启动命令行Shell;

      ③为了使得目标程序在攻击之后正常终止,Shellcode中还可以调用exit()函数退出当前进程;

      下图为汇编语言班Shellcode代码以及Opcode版Windows本地Shellcode;

      ⑤上述代码釆用了硬编码的system()函数地址;硬编码即直接找到此函数在内存中的地址,在代码中直接使用函数的地址进行调用;

      ⑥使用Kernel32.dll中的LoadLibrary()和GetProcAddress()函数提供了运行时刻加载指定动态链接库,及查询指定函数加载地址的功能,因此Windows平台上的Shellcode通常使用这两个API接口函数来加载并查询其他所需函数地址;

    • Windows远程Shellcode实例分析:

      Windows远程Shellcode的C语言实现的基本过程为:

      ①创建一个服务器端socket,并在指定的端口上监听;

      ②通过accep()接受客户端的网络连接;

      ③创建子进程,运行“cmd.exe”,启动命令行;

      ④创建两个管道,命令管道将服务器端socket接收(recv)到的客户端通过网络输入的执行命令,连接至cmd.exe的标准输入;然后输出管道将cmd.exe的标准输出连接至服务器端socket的发送(send),通过网络将运行结果反馈给客户端;


1.5 堆溢出攻击

  • 堆溢出:Linux内存空间中的数据区.data段为包含已初始化的全局数据,.bss段包含未经初始化的数据,运行时刻动态分配内存的数据区heap等,在这些内存数据区有着共同的特点即数据分配与增长方向是从低地址向高地址,而非栈从高地址向低地址的增长方向,因此称这些缓冲区溢出的情况为堆溢出;

  • 函数指针改写

    • 堆溢出的函数指针改写攻击示意图如下,需要被溢出的缓冲区临近全局函数指针存储地址,且在其低地址方向;

    • 在符合这种变量布局的条件下,当向缓冲区填充数据时,如果没有边界判断和控制的话,那么缓冲区溢出之后就会自然地覆盖函数指针所在的内存区,从而改写函数指针的指向地址,攻击者只要能够将该函数指针指向恶意构造的Shellcode入口地址,在程序使用I函数指针调用原先期望的函数时,就会转而执行Shellcode;

  • C++类对象虚函数表改写

    • C++类通过虚函数提供了一种Late binding运行过程绑定的机制,编译器为每个包含虚函数的类建立起虚函数表(vtable)、存放虚函数的地址,并在每个类对象的内存区中放入一个纸箱虚函数表的指针,通常称为虚函数指针vtpr
    • 对于使用了虚函数机制的C++类,如果它的类成员变量中存在可被溢出的缓冲区,那么就可以进行堆溢出攻击,通过覆盖类对象的虚函数指针,使其指向一个特殊构造的虚函数表,从而转向执行攻击者恶意注入的指令
  • Linux下堆管理glibc库free()函数本身漏洞

    • Linux操作系统中的堆管理是通过glibc库实现的,glibc 2.2.4及以下版本的地内存管理算法是使用了 Doug Lea的实现方式,称为dlmalloc,而glibc 2.2.5及以上版用则采用了 Wolfram Gloger 的ptmalloc/ptmalloc2 代码,ptmalloc 代码是从 dlmalloc 代码移植过来的主要目的是增加了对多线程环境的支持,同时进一步优化了内存分配和回收的算法

    • dlmalloc实现的glibc库中的内存块结构使用了被称为的双向循环链表来存储内存空闲块信息,并使用了两个来完成对链表的插入和删除操作;

    • glibc库的free()函数为我们提供了这样的机会,free()函数在处理内存块回收时,需要将已被释放的空闲块和与之相邻的空闲块进行合并,因此将会把符合条件的空闲块熊Bin链表中unlink摘出来,合并之后再讲新的空闲块插回链表中;


1.6 缓冲区溢出攻击的防御技术

  • 尝试杜绝溢出的防御技术

  • 解决缓冲区溢出攻击最根本的办法是编写正确的、不存在缓冲区溢出安全漏洞的软件代码,但由C/C++语言作为效率优先的语言,很容易就会出现缓冲区溢出;

    • 研究人员开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序,包括一些高级的查错程序,如fault injection通过Fuzz注入测试来寻找代码的安全漏洞,还有一些分析工具用于侦测缓冲区溢出漏洞是否存在;
    • 另外,一些研究者在编译器上引入针对缓冲区的边界保护检查机制
  • 允许溢出但不让程序改变执行流程的防御技术

  • 第二种防御技术允许溢出发生,但对可能影响到程序流程的关键数据结构实施严密的安全保护,不让程序改变其执行流程,从而阻断溢出攻击;

    • StackGuard是最早提出也是最经典的此类技术,针对覆盖函数返回地址的溢出攻击,通过对编译器gcc加补丁,使得在函数入口处能够自动地在栈中返冋地址的前而生成一个“Canary”(金丝雀)检测标记,在函数调用结束检测该标记是否改变来阻止溢出改变返回地址,从而阻止缓冲区溢出攻击;
  • 无法让攻击代码执行的防御技术

  • 第三种防御技术尝试解决冯•诺伊曼体系的本质缺陷,通过堆栈不可执行限制来防御缓冲区溢出攻击;

  • 1A64、AMD64、Alpha等新的CPU硬件体系框架都引入对基于硬件NX保护机制,从硬件上支持对特定内存帧设置成不可执行,Windows XPSP2、 Linux内核2.6及以后版本都支持硬件NX保护机制,与操作系统配合来提升系统的安全性。

  • 各种操作系统也通过一些内核补丁或内建机制来支持堆栈不可执行

  • 针对堆栈不可执行的防御措施,黑客们提出了 return-2-libc攻击技术,这种攻击方法不是让CPU去执行攻击者的注入代码,而是让CPU按照特定顺序去执行系统中己经存在的代码,借助这些按照特定顺序组合的代码片断,组合攻击者要完成的功能,而这些代码又存在于可执行的内存中;


3.学习中遇到的问题及解决

  • 问题1 :确实有很多不懂的名词;
  • 解决1 :一通百度到底~

4.实践总结

这次的实践幸亏老师取消了后面的实践作业,我是真的一点点的看不懂!怪我太菜,前面的那些知识点也是看了好久,查了不少资料才算是了解了皮毛~ 攻防真是一个包罗万象的大船,装着密码学知识、网络知识、攻击知识、防御知识等等,目前我还只是参观了大船的一部分,后面还得继续参观呀~

参考资料

posted @ 2020-05-05 16:53  Jody9123  阅读(556)  评论(0编辑  收藏  举报