zoukankan      html  css  js  c++  java
  • 逆向进阶

    20175314 2020-3 《网络对抗技术》Exp1Plus 逆向进阶 Week3

    一、实践内容

    Task1 (5-10分)

    • 自己编写一个64位shellcode(参考shellcode指导)。
    • 自己编写一个有漏洞的64位C程序,功能类似我们实验1中的样例pwn1。使用自己编写的shellcode进行注入。

    Task 2 (5-10分)

    • 进一步学习并做ret2lib及rop的实践,以绕过“堆栈执行保护”(参考ROP)。

    Task 3 (5-25分)

    • 可研究实践任何绕过前面预设条件的攻击方法;可研究Windows平台的类似技术实践。
    • 或任何自己想弄明白的相关问题。包括非编程实践,如:我们当前的程序还有这样的漏洞吗?

    二、基础知识

    安装必要软件包

    • root用户权限下
    apt-get install gcc-multilib//安装gcc-multilib(生成多平台代码)
    apt-get install wxhexeditor//安装wxhexeditor(16进制文本编辑器)
    

    预备知识

    • Linux X86和X64的区别

    • 在开始前学习并实践Shellcode基础

    • 非常好用的Shellcode生成器

    • ROP全称为Retrun-oriented Programmming(面向返回的编程)是一种新型的基于代码复用技术的攻击,攻击者从已有的库或可执行文件中提取指令片段,构建恶意代码,ROP攻击同缓冲区溢出攻击,格式化字符串漏洞攻击不同,是一种全新的攻击方式,它利用代码复用技术。不同于return-to-libc攻击(攻击者不需要可执行的栈,甚至不需要shellcode,通过将程序的控制权跳转到系统自己的可执行代码),R0P攻击攻击之处在于以ret指令结尾的函数代码片段,而不是整个函数本身去完成预定的操作。

      • 从广义角度讲,return-to-libc攻击ROP攻击的特例。
      • 最初ROP攻击实现在x86体系结构下,随后扩展到各种体系结构。
      • 与以往攻击技术不同的是,ROP恶意代码不包含任何指令,将自己的恶意代码隐藏在正常代码中。因而,它可以绕过W⊕X的防御技术。

    实践原理

    • Linux下ELF格式

    • 重写shellcode汇编代码:shellcode要将字符串/bin/sh作为参数传递,shellcode被写入缓冲区后,代码的位置是不固定的,因为call指令执行的第一个动作就是将下一条指令的地址压栈,所以利用call指令能够得到/bin/sh这个字符串,我们把字符串安排在call指令后,目的就是要把它压入栈中。

    • ROP的核心思想:

      • 攻击者扫描已有的动态链接库和可执行文件,提取出可以利用的指令片段gadget,这些指令片段均以ret指令结尾,即用ret指令实现指令片段执行流的衔接。
      • 操作系统通过栈来进行函数的调用和返回,函数的调用和返回就是通过压栈和出栈来实现的。每个程序都会维护一个程序运行栈,栈为所有函数共享,每次函数调用,系统会分配一个栈桢给当前被调用函数,用于参数的传递、局部变量的维护、返回地址的填入等。栈帧是程序运行栈的一部分,在Linux中 ,通过%esp%ebp寄存器维护栈顶指针和栈帧的起始地址,%eip是程序计数器寄存器。
      • 而ROP攻击则是利用以ret结尾的程序片段 ,操作这些栈相关寄存器,控制程的流程,执行相应的gadget,实施攻击者预设目标。

    二、实验步骤

    1、Task1

    • 1、使用vim编写shellcode.c

    • 2、gcc -o shellcode shellcode.c编译生成可执行文件,执行查看效果

    • 3、objdump -d shellcode > shellcode.s 生成反汇编代码,找到main函数

    • 4、参照上面的反汇编代码使用vim重新编写scode.s

    as -o scode.o scode.s      //编译
    ld -o scode scode.o        //连接
    ./scode                    //运行
    
    以上汇编代码的解释
    jmp   cl                   #跳到cl标签处,即call pp
    call  pp                   #将字符串压栈,同时返回到上面pp标签处
    popq  %rcx                 #将字符串/bin/sh的地址存入rcx(通用寄存器,也可以选择其他寄存器)
    pushq %rbp                 #本条指令及以下两条指令都是在建立一个新的栈空间
    mov   %rsp, %rbp           #真正注入的shellcode代码可以不用创建这个栈
    subq  $0x20, %rsp          #但是bin/sh字符串是放在了代码段里不允许修改的空间
    movq  %rcx, -0x10(%rbp)    #将字符串复制到栈
    movq  $0x0,-0x8(%rbp)     #创建调用exec时的参数name[1],将它置0
    lea   -0x10(%rbp), %rsi    #这是execve第二个参数,它需要**类型,所以用lea传送地址给rsi
    mov   -0x10(%rbp), %rdi    #mov将字符串传给rdi,这是execve第一个参数
    mov   $59, %rax            #59是execve的系统调用号,在/usr/include/asm/unistd_64.h里可以查询到
    syscall                #系统调用,可以取代int 0x80
    
    • 5、objdump反汇编scode(这里使用可以直接输出shellcode的命令)

    • 6、在C语言程序中测试

    因为64位系统地址宽度是64位的,所以要使用long类型
    ret作为main的第一个局部变量,必定是存储在main的栈空间内
    其中long * ret 这条指令占据了一个64位, 当ret地址加1(64位)时,ret就到到达栈的基址位置(rbp)
    main函数的返回地址还在栈基址之上的高地址中,距离rbp还有64位宽度,所以ret需要加上2(64位),才能到达main的返回地址的保存位置
    (*ret) = (long)code,用code的地址将main返回地址覆盖
    

    三、遇到的问题

    问题:汇编报错nasm:fatal:unable to open output file

    • 解决方案:路径中包含_/+/-等符号,重新设置路径即可编译通过

    问题:C语言程序测试Shellcode段错误

    • 解决方案:GDB调试看main函数的调用,Shellcode是以全局字符数组变量的形式存储在进程堆栈中的数据段中,数据段是没有可执行权限的,所以一旦PC寄存器进入到这里面,那么程序就会报错。用命令将要运行的程序用execstack解除可执行栈的保护

    四、参考资料

  • 相关阅读:
    target runtime apache v6.0 not defined解决
    java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
    The valid characters are defined in RFC 7230 and RFC 3986问题
    invalid END header解决方法
    You have more than one version of ‘org.apache.commons.logging.Log’ visible, which is not allowed问题解决
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    在eclipse中import java web项目时遇到的一些问题并将该项目通过tomcat发布
    java byte转string 涉及到字节流中有中文
    spring+mybatis框架搭建时遇到Mapped Statements collection does not contain value for...的错误
    试试看读一下Zepto源码
  • 原文地址:https://www.cnblogs.com/SANFENs/p/12452195.html
Copyright © 2011-2022 走看看