(信息安全概论作业)缓冲区溢出问题—C语言—溢出攻击

目录

题目:

作业代码:(编译环境devc++,12位时绕开口令)

1.当从键盘输入“1234567”、“12345678”、“11112222”时,程序执行完图中所标记的 strcpy 语句之后,堆栈会如何变化?此时程序的最终执行结果将会是什么?运行程序进行验证。

2.当满足什么条件时,就可以在不知道真实口令的情况下绕过口令验证功能?为什么?

结论:


缓冲区溢出作业

题目:

下图 a 为一段 C 语言源程序,其中,编译器为 authenticated 变量分配 4 个字节空间,为 buffer 变量分配 8 个字节空间。程序执行完图中所标记的“strcpy(buffer,password); ”语句时,堆栈的布局如下图 b 所示(注意:低字节数据保存在低地址,例如字符串“1234 ”存储状态为“ 0x34333231 ”)。
图 a 验证口令演示程序
图 b 调用 valid_flag 子程序时的堆栈布局
请分析程序及堆栈特征,回答如下问题:
1 ) 当从键盘输入“ 1234567 ”、“ 12345678 ”、“ 11112222 ”时,程序执行完图中所标记的 strcpy 语句之后,堆栈会如何变化?此时程序的最终执行结果将会是什么?运行程序进行验证。
(2) 当满足什么条件时,就可以在不知道真实口令的情况下绕过口令验证功能?为什么?

作业代码:(编译环境devc++,12位时绕开口令)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define PASSWORD "1234567"


int verify_password(char *password)

{

 int authenticated;

 char buffer[8];

 authenticated=strcmp(password,PASSWORD);

 strcpy(buffer,password);

 return authenticated;

}

int main()

{

 int valid_flag=0;

 char password[1024];

 while(1){

  printf("pleace input password:");

  scanf("%s",&password);

  valid_flag=verify_password(password);

  if(valid_flag==0){

   printf("congratulation.You have passed the verification.\n");

   break;

  }

  else{

   printf("incorrect password\n\n");

  }

 }

}

1.当从键盘输入“1234567”、“12345678”、“11112222”时,程序执行完图中所标记的 strcpy 语句之后,堆栈会如何变化?此时程序的最终执行结果将会是什么?运行程序进行验证。

(1)1234567

堆栈:

0x34333231

0x00373635

00000000 00000000 00000000 00000000

EBP

返回

执行结果为:

(2)12345678

堆栈:

0x34333231

0x38373635

00000000 00000000 00000000 00000000

EBP

返回地址

执行结果为:

Devc++

Code clock

(3)11112222

堆栈:

0x31313131

0x32323232

11111111 11111111 11111111 00000000

EBP

返回地址

执行结果为:

devc++

Code clock

2.当满足什么条件时,就可以在不知道真实口令的情况下绕过口令验证功能?为什么?

利用缓冲区溢出攻击,可以在不知道真实口令的情况下绕过口令验证功能。

原理分析:

程序中存在一个潜在的漏洞,即使用了 strcpy 函数将用户输入的密码复制到一个缓冲区中,从而可能导致缓冲区溢出攻击,可以通过输入比缓冲区长的密码进行攻击。

而根据本题,当输入的密码长度超过 7个字符时password的长度大于7,使用 strcpy 函数将密码复制到 buffer 数组中时,会出现缓冲区溢出问题,导致内存中的其他数据被覆盖,从而可能篡改 authenticate 的值。

程序验证:

 

规律:

当输入位数为12(code block位数为8),前7位值大于1234567(PASSWORD)时,可以绕过口令验证。

(strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。)

经分析,当就是令strcmp返回0或者正数(即 authenticate 的值为0或正数)时,可以通过缓存溢出篡改authenticate 的值为0;strcmp返回负数(即 authenticate 的值为负数)时,无法实现。

过程分析:

在输入12位密码(code blocks为8位)时,会导致缓冲区溢出。从而将authenticate 的值篡改为0。当authenticate 的值篡改为0时,便表明口令有效,而且绕过验证。

遇到问题:

在输入前7位小于1234567时,strcmp会返回负数(即 authenticate 的值为负数),在我的初步理解里, authenticate 的值为负数与正数一样同样可以被篡改。但是在实际操作中,我发现当以上情况发生时,就无法绕开口令验证。

猜测:

负数的符号位储存为1,而0与正数符号位储存为0,这可能导致缓冲区溢出无法将负数篡改成0。

检验:

对源代码进行修改,加入打印 authenticate 的值的功能。

已知1与-1的四字节二进制值如下。

1:00000000 00000000 00000000 00000001

-1:11111111 11111111 11111111 11111111

经过修改发现1被修改为0,-1被修改为-256。0与-256如下。

0:00000000 00000000 00000000 00000000

-256:11111111 11111111 11111111 00000000

对比可以得出结论,缓冲溢出将最后一个字节覆盖为0,因此-1不能被修改为0。

结论:

当输入位长为12(code block为8)时,且前7位大于等于PASSWORD(1234567)时,可以绕开口令验证。

因为利用缓冲区溢出时,可以修改authenticate 最后一个字节的储存值为0。所以仅当authenticate前3字节存储值为0,才可以将其值修改为0。对于本题便是,authenticate值为-1或任意负数,则无法完成篡改。authenticate值为正数且小于512(包括1)时,则可以完成篡改。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拉进人山人海

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

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

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

打赏作者

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

抵扣说明:

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

余额充值