软件安全实验——lab6(缓冲区溢出2:使用jmp esp或者call esp方法和修改函数指针)

Task 1

下面的程序具有缓冲区溢出,利用jmp esp或者call esp进行溢出

/* stackesp.c */

/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
/* sudo sysctl -w kernel.randomize_va_space=2 then use jmp esp or call esp(no nops) */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//use jmp esp or call esp
int someint=0xe4ffd4ff; //e4ff 对应jmp esp, d4ff对应call esp
int bof(char *str)
{
   char buffer[12];
   strcpy(buffer, str);
   return 1;
}
int main(int argc, char **argv)
{
   char str[517];
   FILE *badfile;
   printf("%x\n",&someint);
   badfile = fopen("badfile", "r");
   fread(str, sizeof(char), 517, badfile);
   bof(str);

   printf("Returned Properly\n");
   return 1;
}

实验原理:
利用栈溢出,将bof函数堆栈帧中的返回地址覆盖为jmp esp or call esp指令的地址,CPU执行到返回地址处时,它会执行jmp esp or call esp指令,执行完这个指令之后,CPU会返回到被中断指令的下一条指令处接着执行,我把Shellcode放到这个被中断指令处,CPU就会执行Shellcode,从而实现我的攻击。

第一步:打开内存地址随机化

$sudo sysctl -w kernel.randomize_va_space=2

第二步:编译上面的程序为Set-UID程序,注意加上-fno-stack-protector进行编译

#gcc -z execstack -fno-stack-protector stackesp.c -o stackesp

设置Set-Uid

#chmod 4755 stackesp

在这里插入图片描述

第三步:bof的返回地址

进入gdb,对stackesp进行gdb,首先查看bof的起始位置和返回地址.
在这里插入图片描述
在这里插入图片描述

第四步:确定缓冲区的位置

为了确定缓冲区的位置,先在badfile里写入了AAAA
在这里插入图片描述

第五步:返回地址和缓冲区之间的距离

查看ESP之后,我们可以知道返回地址和缓冲区之间相差了6×AAAA个字节
在这里插入图片描述

所以我们再badfile中写入24个A来覆盖缓冲区,之后接上程序输出的jmp esp和call esp指令的地址0804a024 ,再接上shellcode
在这里插入图片描述

Task 2

/* overfun.c */

/* This program has a buffer overflow vulnerability. */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int good(int addr) {
        printf("Address of hmm: %p\n", addr);
}
 int hmm() {
        printf("Win.\n");
        setuid(geteuid());
        execl("/bin/sh", "sh", NULL);
}
extern char **environ;
int main(int argc, char **argv) {
        int i, limit;
        for(i = 0; environ[i] != NULL; i++)
        memset(environ[i], 0x00, strlen(environ[i]));//将环境变量清空,所以这里不能用环境变量写入shellcode来攻击
        int (*fptr)(int) = good;//函数指针fptr指向good
        char buf[32];
        strcpy(buf,argv[1]);
        int (*hmmptr)(int) = hmm;  //函数指针hmmptr指向hmm
        (*fptr)((int)hmmptr);    //相当于good((int)hmmptr)传入hmm函数的地址
        return 0;
}

在这里插入图片描述

实验原理:
程序主要就是运行了good()函数(输出hmm函数的地址),我们目的就是将程序中指向good函数的fptr指针重定向为hmm,的这样程序就会执行hmm函数中的shellcode,从而获取root权限。
在这里插入图片描述

第一步:打开内存地址随机化

$sudo sysctl -w kernel.randomize_va_space=2

第二步:编译上面的程序为Set-UID程序,注意加上-fno-stack-protector进行编译

#gcc -z execstack -fno-stack-protector overfun.c -o overfun

设置Set-Uid

#chmod 4755 overfun

在这里插入图片描述

第三步:strcpy函数的返回地址

在main函数中找到strcpy函数的返回地址(0x0804964e),之后设置断点,(因为在strcpy函数之前,已经把good函数的地址赋给fptr指针了,我们首先就是要找到good函数的地址的位置)
输入AAAA并运行程序:
在这里插入图片描述

查看ESP之后,我们可以知道输入的字符串argv与good函数起始地址(0x08048554)之间之间相差了9×AAAA个字节

第四步:hmm函数的地址

写入36个字节来覆盖缓冲区,之后接上hmm函数的地址来代替good函数的地址,下面是三种找到hmm函数地址的方法
在这里插入图片描述
在这里插入图片描述

第五步:攻击

程序执行之后就会跳转到hmm函数,这样程序就会执行hmm函数中的shellcode,从而获取root权限。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值