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

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

1.实践内容

1.1 软件安全概述

  • 安全漏洞(Vulnerability)的定义:在系统安全流程、设计、实现或内部控制中所存在的缺陷或弱点,能够被攻击者所利用并导致安全侵害或对系统安全策略的违反。

  • 安全漏洞的范畴不限于软件安全漏洞,还包括硬件、个人与组织管理中存在的、能够被攻击者利用来破坏安全策略的弱点。软件安全漏洞是目前最常见,也是影响范围最大的安全漏洞类型。

  • 软件安全困境的原因:复杂性、可扩展性和连通性,软件的这三个要素共同作用,使得软件的安全风险管理成为一个巨大的挑战,从而很难根除安全漏洞。

  • 软件安全漏洞类型
    内存安全违规类:内存安全违规类漏洞是在软件开发过程中在处理RAM内存访问时所引入的安全缺陷,如缓冲区漏洞溢出和Double Free、Use-after-Free等不安全指针问题等。不安全指针是指在计算机程序中存在的并没有指向适当类型对象的非法指针,在对这些指针进行引用时,往往会发生一些不可预期的后果,导致程序内存访问错误。
    输入验证类:输入验证类安全漏洞是指软件程序在对用户输入进行数据验证存在的错误,没有保证输入数据的正确性、合法性和安全性,从而导致可能被恶意攻击与利用。输入验证类安全漏洞根据输入位置、恶意输入内容被软件程序的使用方式的不同,又包含格式化字符串、SQL注入、代码注入、远程文件包含、目录遍历、XSS、HTTP Header注入、HTTP响应分割错误等多种安全漏洞技术形式。
    竞争条件类:竞争条件类缺陷是系统或进程中一类比较特殊的错误,通常在涉及多进程或多线程处理的程序中出现,是指处理进程的输出或者结果无法预测,并依赖于其他进程事件发生的次序或时间时,所导致的错误。
    权限混淆与提升类:权限混淆与提升类漏洞是指计算机程序由于自身编程疏忽或被第三方欺骗,从而滥用其权限,或赋予第三方不该给予的权限。具体技术形式主要有:Web应用程序中的跨站请求伪造(CSRF)、Clickjacking、FTP反弹攻击、权限提升、“越狱”(jailbreak)等。

1.2 缓冲区溢出基础概念

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

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

  • 缓冲区溢出漏洞的三种具体技术形态(根据缓冲区在进程内存空间中的位置不同分类):栈溢出堆溢出内核溢出
    栈溢出是指存储在栈上的一些缓冲区 变量由于存在缺乏边界保护问题,能够被溢出并修改栈上的敏感信息(通常是返回地址),从而导致程序流程的改变。
    堆溢出则是存储在堆上的缓冲区变量缺乏边界保护所遭受溢出攻击的安全问题。
    内核溢出漏洞存在于一些内核模块或程序中,是由于进程内存空间内核态中存储的缓冲区变量被溢出造成的。

1.3 Linux平台上的栈溢出与Shellcode

1.3.1 Linux平台栈溢出攻击技术

  • Linux平台中的栈溢出攻击按照攻击技术的构造方式不同,主要有NSRRNSRS三种模式。
    NSR模式:主要适用于被溢出的缓冲区变量比较大,足以容纳Shellcode的情况,其攻击数据从低地址到高地址的构造方式是一堆Nop指令(即空操作指令)之后填充Shellcode,再加上一些期望覆盖RET返回地址的跳转地址,从而构成了NSR攻击数据缓冲区。
    RNS模式:一般用于被溢出的变量比较小,不足以容纳Shellcode的情况。攻击数据从低地址到高地址的构造方式是首先填充一些期望覆盖RET返回地址的跳转地址,然后是一堆Nop指令填充出“着陆区”,最后再是Shellcode。在溢出攻击之后,攻击数据将在RET区段即溢出了目标漏洞程序的小缓冲区,并覆盖了栈中的返回地址,然后跳转至Nop指令所构成的“着陆区”",并最终执行Shellcode。
    RS模式:在这种模式下能够精确地定位出Shellcode在目标漏洞程序进程空间中的起始地址,因此也就无须引入Nop空指令构建“着陆区”。这种模式是将Shellcode 放置在目标漏洞程序执行时的环境变量中,由于环境变量是位于Linux进程空间的栈底位置,因而不会受到各种变量内存分配与对齐因素的影响,其位置是固定的,可以通过如下公式进行计算: ret = 0xc0000000 - sizeof(void *) - sizeof(FILENAME) - sizeof(Shellcode)

  • Linux平台上的远程栈溢出攻击的原理和本地栈溢出攻击是一样的,区别为
    用户输入传递的途径不同:本地栈溢出的用户输入传递途径主要为argv命令行输入、文件输入等,远程栈溢出的用户输入传递途径则是通过网络。
    Shellcode的便携方式不同:本地栈溢出攻击中的Shellcode主要会包含提升至较当前运行用户权限更高的权限,并给出本地Shell访问,而远程栈溢出攻击的Shellcode则需要将Shell访问与网络连接起来,给出一个远程的Shell访问。

  • NSR和RNS模式也都适用于远程栈溢出攻击,RS模式只能用于本地缓冲区溢出攻击。

1.3.2 Linux平台的Shellcode实现技术

  • Shellcode是一段机器指令,对于我们通常接触的IA32架构平台,Shellcode就是符合Intel 32位指令规范的一串CPU指令,被用于溢出之后改变系统正常流程,转而执行Shellcode以完成渗透测试者的攻击目的,通常是为他提供一个访问系统的本地或远程命令访问(即Shell)。

  • Linux本地Shellcode实现机制
    (1)先用高级编程语言,通常用C,来编写Shellcode 程序;
    (2)编译并反汇编调试这个Shellcode程序:
    (3)从汇编语言代码级别分析程序执行流程:
    (4)整理生成的汇编代码,尽量减小它的体积并使它可注入,并可通过嵌入C语言进行运行测试和调试;
    (5)提取汇编代码所对应的opcode二进制指令,创建Shellcode指令数组。

  • Linux远程Shellcode实现机制:Linux系统上的远程Shellcode的实现原理与本地Shellcode完全一致,实现方法步骤也跟本地Shellcode一致。但是Linux远程Shellcode需要让攻击目标程序创建socket监听指定的端口等待客户端连接,启动一个命令行Shell,并将命令行的输入输出与socket绑定。

1.4 Windows平台上的栈溢出与Shellcode

1.4.1 Windows平台栈溢出攻击技术机理

  • Windows操作系统与Linux操作系统在栈溢出漏洞方面的差异
    (1)对程序运行过程中废弃栈的处理方式差异
    Windows平台会向废弃栈中写入一些随机的数据,而Linux则不会进行任何的处理。Windows系统在调用完成函数之后,会对废弃栈进行处理,从而破坏了在溢出缓冲区中保存的Shellcode,即使成功进行了渗透攻击覆盖了栈中的返回地址,但覆盖返回地址所指向的Shellcode已经失效,这样就无法执行攻击者指定的指令达成攻击目的
    (2)进程内存空间的布局差异
    Linux进程内存空间中栈底指针在0xc0000000之下,即一般栈中变量的位置都在0xf地址附近,在这些地址中没有空字节。Windows 平台的栈位置处于0x00FFFFFF 以下的用户内存空间,一般为0x0012地址附近,而这些内存地址的首字节均为0x00 空字节。我们在栈中植入Shellcode的起始位置,即要覆盖原先返回地址的跳转地址肯定也拥有空字节,此时我们所构造出来的“RNS"模式攻击数据中在“R"的位置上就存在着空字节,而这样的攻击数据在漏洞程序中的一些字符串拷贝和操作函数中将被截断,丢弃掉空字节之后的nop和Shellcode,致使无法成功地进行溢出攻击。
    在Windows平台上也没有Linux平台上通过SUID/SGID程序能够提升当前用户执行权限的机制。
    (3)系统功能调用的实现方式差异
    Linux系统中通过“int80”中断处理来调用系统功能,而Windows系统则是通过操作系统中更为复杂的API及内核处理例程调用链来完成系统功能调用,对应用程序直接可见的是应用层中如Kernel32.dll、User32.dIl 等系统动态链接库中导出的一些系统API接口函数。

1.4.2 Windows平台Shellcode实现技术

  • Windows本地Shellcode
    在Windows平台上,典型的本地Shellcode同样也是启动一个命令行Shell,即“command.com”或“cmd.exe”,Windows32的系统API中提供了system()函数调用,可以用于启动指定程序或运行特定命令,在调用system(“command.com”)之后即可启动命令行程序。
    在Windows平台上Shellcode的编写过程中,可以使用Kernel32.dll中的LoadLibrary和GetProcAddress()函数来装载其他所需的函数,并查询获得函数入口地址。
    对于较早版本的Windows操作系统而言,这两个函数所在的Kernel32.dll链接库都会被映射至目标程序进程空间的相同位置,同时它们的函数入口也是相对固定的,因此我们可以在Shellcode中采用硬编码函数地址,但是这种方法实现的Shellcode只能用于特定的Windows版本。
    为构建更具通用性的Shellcode,有一种动态搜索Kernel32.dll内存空间以获取函数入口地址的方法,首先通过进程环境块(PEB)的结构分析获取Kernel32.dll加载基址,然后从这个DLL的导出函数表中通过函数名称查询获得所需函数的入口地址。

  • Windows远程Shellcode
    大致过程
    (1)创建一个服务器端socket,并在指定的端口上监听;
    (2)通过accept()接受客户端的网络连接:
    (3)创建子进程,运行“cmd.exe",启动命令行;
    (4)创建两个管道,命令管道将服务器端socket接收(recv) 到的客户端通过网络输入的执行命令,连接至cmd.exe的标准输入:然后输出管道将cmd.exe的标准输出连接公服务器端socket的发送( send),通过网络将运行结果反馈给客户端。

1.5 堆溢出攻击

  • 堆溢较栈溢出具有更高的难度,最重要的原因在于堆中并没有可以直接覆盖并修改指令寄存器指针的返回地址,因此往往需要利用在堆中一些会影响程序执行流程的关键变量,如函数指针、C++类对象中的虚函数表,或者挖掘出堆中进行数据操作时可能存在的向指定内存地址改写内容的漏洞机会。

  • 函数指针改写

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

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

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

  • 尝试杜绝溢出的防御技术:最根本的办法是编写正确的、不存在缓冲区溢出安全漏洞的软件代码;编写一些高级的查错程序,如fault injection等;通过Fuzz注入测试来寻找代码的安全漏洞,还有一些分析工具用于侦测缓冲区溢出漏洞是否存在;在编译器上引入针对缓冲区的边界保护检查机制。但不能完全地消除缓冲区溢出攻击的可能性。

  • 允许溢出但不让程序改变执行流程的防御技术:StackGuard技术、PointGuard、ProPolice、Stack Shield等技术;C++中的虚函数表指针、覆盖SEH异常处理结构等。

  • 无法让攻击代码执行的防御技术:A64、AMD64、Alpha等新的CPU硬件体系框架都引入对基于硬件NX保护机制,从硬件上支持对特定内存页设置成不可执行;各种操作系统也通过一些内核补丁或内建机制来支持堆栈不可执行,如Linux平台上的PaX堆栈不可执行内核补丁, Solaris/SPARC的栈不可执行保护、数据段不可执行内核补丁、Windows的DEP数据执行保护机制等。此外目前主流操作系统也普遍使用了ASLR内存地址布局随机化机制。

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

  • 问题1:最大的问题是对于一些知识都清楚或是不够理解
  • 问题1解决方案:多查多学多理解多积累吧

4.实践总结

  在这章学习的最后作者写道:“缓冲区溢出虽然已经是一个很“古老”的安全问题,安全研究者与软件厂商也已经提出了各种各样的解决办法和防护手段,黑客们总是能够“见招拆招",继续进行着攻防博弈。”其实不仅仅是缓冲区溢出是这样,软件、系统以及网络中存在着很多类似这样的,即使防护手段和解决办法一直在更新,但总存在安全漏洞,而且层出不穷,安全漏洞问题是不可避免的,虽然现实如此,但我们不能破罐子破摔,毕竟在这个网络时代,网络的使用、计算机的使用已成为人们生活中不可或缺的一部分,因此我们要一直与安全漏洞与黑客作斗争,保护我们的系统,保护网络世界的安全。

参考资料

  • [《网络攻防技术与实践》诸葛建伟著]

posted on 2020-05-06 15:00  20199317-程峥华  阅读(246)  评论(0编辑  收藏  举报

导航