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


    作业所属课程:https://edu.cnblogs.com/campus/besti/19attackdefense/
    作业要求:https://edu.cnblogs.com/campus/besti/19attackdefense/homework/10723

    实践内容

    1、安全漏洞
    (1)包括软件、硬件、个人、组织管理
    (2)基本元素
    1)系统的脆弱性或缺陷
    2)攻击者对缺陷的可访问性
    3)攻击者对缺陷的可利用性
    2、软件安全困境
    复杂性、可扩展性、连通性
    3、软件安全漏洞类型
    (1)内存安全违规类
    1)程序在处理RAM内存访问时引入的安全缺陷。如缓冲区溢出漏洞和Double Free、Use-after-Free等不安全指针问题。
    2)C/C++:支持任意内存分配和归还、任意指针计算、转换,未保护内存安全。
    Java:禁用指针计算和转换。实施内存垃圾跟踪和回收等机制,可有效解决这样的漏洞。
    (2)输入验证类
    1)程序对用户输入进行数据验证存在的错误,没有保证输入数据的正确性、合法性和安全性。
    2)格式化字符串、SQL注入、代码注入、远程文件包含、目录遍历、XSS、HTTP Header注入、HTTP相应分割错误等
    (3)竞争条件类
    1)涉及多线程或者多进程处理的程序中出现。处理进程的输出或结果无法预测。
    2)TOCTTOU,像是读脏字
    (4)权限混淆与提升类
    1)计算机由于自身编程疏忽或被第三方欺骗,从而滥用权限,或赋予第三方不该给与的权限。
    2)WEB应用程序中的跨站请求伪造、Clickjacking、FTP反弹攻击、权限提升、越狱等
    3)FTP反弹攻击 A------>FTP(proxy)------>B

    缓冲区溢出基础概念

    1、在计算机程序向特定缓冲区内填充数据时,超出了缓冲区本身的容量,导致外溢数据覆盖相邻内存空间合法数据,改变程序执行流程破坏系统运行完整性。
    2、常见于C/C++中的memcpy()(不会被所截断)和strcpy()
    3、根本原因:存储程序,数据和程序都在同一内存中存储。

    编译器和调试器的使用

    1、C/C++ 经过(gcc -c)编译和连接(gcc -o)生成可执行文件(也可以直接使用gcc -o从源码生成可执行文件)
    2、一般情况下我们无法获得软件的源代码,通过反汇编,读取汇编代码进行分析。
    3、在IA32汇编预言者中,寄存器分为4类
    通用寄存器:ea(b,c,d)x用于普通算数运算,保存数据、地址、偏移量、计数值等。esp(栈指针)
    段寄存器
    控制寄存器:如eip
    其他寄存器:如扩展标志eflags寄存器,由不同标志位组成。用于保存指令执行后的状态和控制指令执行流程的标志信息。

    寄存器名 说明 功能
    eax 累加器 加法乘法指令的缺省寄存器,函数返回值
    ecx 计数器 REP&LOOP循环指令的内定计数器
    edx 除法寄存器 存放整数除法产生的余数
    ebx 基址寄存器 在内存寻址时存放基地址
    esp 栈顶指针寄存器 SS:ESP当前堆栈的栈顶指针
    ebp 栈底指针寄存器 SS:当前堆栈的栈底指针
    esi,dei 源、目标索引寄存器 在字符串操作指令中,DS:ESI指向源串ES:EDI指向目标串
    eip 指令寄存器 CS:EIP指向下一条指令的地址
    eflags 标志寄存器 标志寄存器
    cs 代码段寄存器 当前执行的代码段
    ss 堆栈寄存器 stack segment,当前堆栈段
    ds 数据段寄存器 data segment 当前数据段

    进程内存管理

    1、linux 32bit
    系统为每个进程创建一个虚拟内存地址空间4GB

    空间 位置
    内核态 3-4GB
    用户态 0-3GB
    程序段类型 内容
    .text 程序指令,只读
    .data 静态初始化的数据 可写
    .bss 未经初始化的数据 可写

    堆:从低到高增长
    栈:从高到低增长

    2、Windows 32bit

    空间 位置
    内核态 2-4GB
    用户态 0-2GB

    函数调用过程

    1、栈区:用于动态存储函数之间的调用关系,保证在调用结束后返回到母函数中继续执行
    2、内存的栈区指的是系统栈。
    3、调用过程

    ESP:永远指向最上面一个栈帧的顶部
    EBP:永远指向最上面一个栈帧的底部
    4、函数调用步骤
    (1)参数入栈,将参数从右向左一次压入系统栈中
    (2)返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈中,即EIP。
    (3)代码区跳转:处理器从当前代码区跳转到被调用参数的入口处。
    (4)栈帧调整
    1)保存当前栈帧状态值,EBP入栈,调用结束时恢复用。
    2)将当前栈帧切换到新栈帧(将ESP值装入EBP)
    3)给新栈帧分配空间
    5、函数返回步骤
    (1)保存返回值:通常将函数的返回值写入eax
    (2)弹出当前栈帧,恢复上一个栈帧
    1)在堆栈平衡基础上,给esp加上栈帧的大小,降低栈顶,回收当前栈帧的空间
    2)将当前栈帧底部保存的前栈帧ebp弹入到ebp寄存器,恢复出上一个栈帧
    3)函数返回地址弹给EIP寄存器
    (3)跳转:按照返回地址太欧专母函数中继续执行

    修改邻接变量

    使用strcpy后,后面不够放的数据会被溢出到其他内存中。
    如,编写一个C程序,判断两个字符串是否相同,以获得缓冲区溢出漏洞。

    {
    int authenticated;
    char buffer[8];
    authenticated=strcmp(passwd,PASSWD);
    strcpy(buffer,passwd);
    retrun authenticated;
    }
    

    在这个函数中,将authenticated放在buffer下一句定义。
    1、内存数据:从低位到高位
    数值数据:从高位到低位

    缓冲区溢出攻击

    1、如何找到缓冲区溢出要覆盖的敏感位置?如RET
    2、将敏感位置的值修改成什么?
    3、执行什么代码达到攻击目的?

    Linux平台栈溢出

    (针对不同的情况的攻击数据构造不太懂)
    1、NSR:NOP+SHELLCODE+RET
    适用于被溢出的缓冲区变量比较大,足以容纳SHELLCODE的情况
    2、RNS:RET+NOP+SHELLCODE
    适用于被溢出的缓冲区变量比较小,不足以容纳shellcode的情况
    3、RS:RET+SHELLCODE(通过exexve()将shellcode放置在环境变量中传递,不适用远程攻击)
    能够精确定位出shellcode在目标漏洞程序进程空间的起始地址。
    4、软中断:终端服务程序
    硬中断:外部设备进行中断
    5、linux通过int 0x80软中断完成系统调用
    windows通过核心DLL中提供的API接口来完成系统调用

    linux本地shellcode实现机制
    写源代码——>汇编——>消除空字符——>opcode二进制指令代码
    远程shellcode实现机制
    目标程序创建socket监听指定端口等待客户端连接
    启动shell,将命令行的输入输出与socket绑定

    windows平台栈溢出

    windows中栈溢出攻击较难
    (1)对程序运行过程中会对回收的废弃栈进行随机字符填充,会破坏在溢出缓冲区中保存的shellcode
    (2)进程内存空间首字节为00,在进行复制到缓冲区中时,会因为是空字符被截断
    (3)系统功能调用的实现方式更加复杂
    对于(1)(2)可以使用系统核心的JMP ESP跳转到地址高位解决,ESP指向的是nop和shellcode的位置。这个指令可以在1-2GB中装载的系统核心DLL中找到。
    攻击步骤:
    1)创建客户端socket,绑定端口监听
    2)组装shellcode数据,使得溢出后,在RET上的指令地址为“JMP ESP”所在的地址
    3)通过socket进行send()

    硬编码:数据嵌入源代码
    最简单的shellcode:
    system(“command.com”)可以用于启动命令行程序。该函数在windows XP特定版本的目标程序内存空间中的加载地址为0x77bf93c7,在shellcode中使用call 0x77bf93c7,让EIP指令寄存器跳转至硬编码的函数入口地址执行。只适用于特定的环境下的特定目标程序。
    一般需要将所需函数的动态链接库装载至目标程序中,然后查询获得该函数加载地址。Kernel32.dll中的LoadLibrary():加载msvct.dll动态链接库,GetProcAddress()函数获得system函数的加载入口地址。

    远程栈溢出步骤:
    (1)创建一个服务器端socket,并在指定的端口上监听。
    (2)通过accept()接受客户端的网络连接。
    (3)创建子进程,运行cmd.exe,启动命令行。
    (4)创建两个管道,命令管道和输出管道

    堆溢出攻击

    堆的结构:堆首(位置、是否空闲)+堆身(数据)
    堆表:空表(双向链表,每个链最多4个node)、快表(单向链表)

    空表:会出现块合并
    可以有次优解,找零钱的分配方式

    快表:不会出现块合并
    只会分配正好合适的块堆

    堆溢出
    如空表:双向链表,在分配,回收或者合并的时候,修改指针。

    (1)函数指针改写
    (2)C++类对象虚函数表改写

    (3)Linux下堆管理glibc库free()函数本身漏洞

    缓冲区溢出攻击的防御技术
    (1)杜绝溢出的防御技术
    编程安全意识提高、安全测试、在编译器上引入缓冲区的边界保护检查机制
    (2)允许溢出,但不允许程序改变执行流程,保护关键数据结构,StarkGuard技术
    如:在RET返回地址前生成一个Canary检测标记,在函数调用结束后,用来检测是否因为溢出改变了返回地址。ro
    其他:PointGuard、ProPolice、Stack Shield等技术。
    (3)解决冯诺依曼体系的本质缺陷。通过堆栈不可执行限制来防御缓冲区溢出攻击。
    如:基于硬件NX保护机制
    内核补丁或内建机制:
    linux:PaX堆栈不可执行内核补丁、Solaris/SPARC的栈不可执行保护、数据段不可执行的内核补丁
    windows:DEP数据执行保护机制
    ASLR内存地址布局随机化机制。在随机的内存位置上加载函数地址和堆栈起始地址。
    而黑客通过return-2-libc攻击技术,让cpu按照特定顺序执行系统中已经存在的代码,借助按照特定顺序组合的代码片段,组合成攻击效果。
    对于ASLR:采用Heap Spraying技术,利用javascript特性,构造(大量)N+S
    JIT Spraying技术

    遇到的问题

    栈溢出构造攻击数据,不知道具体的工作细节
    堆溢出对堆的工作机理不了解,找了点别的资料看了一下

    学习心得与体会

    操作系统的工作流程的描述,好像是离不开一些内在的函数的描述。一带上一些函数,就会有点乱。
    要有读16进制数的意识,慢慢捋一捋。

    参考文献

    《网络攻防技术与实践》
    《0Day安全:软件漏洞分析技术》

  • 相关阅读:
    Grumpy: Go 上运行 Python!
    Qt5.7.0配置选项(configure非常详细的参数)
    vs2010 2013 2015+ 必备插件精选(15个)
    solr与.net主从复制
    MVC5模板部署到mono
    solr主从复制
    CentOS 5.5安装图解教程
    VMware7安装CentOS6.5教程
    VMware安装CentOS 图文教程
    在VirtualBox下安装CentOS教程(截图版)
  • 原文地址:https://www.cnblogs.com/eosmomo/p/12839561.html
Copyright © 2020-2023  润新知