下面的代码为一个64位程序的反汇编代码,在需要覆盖ebp的情况下,需要填充多少个字节到buf的缓冲区,才能改变程序的执行流程? _int64 stack_overflow() { char buf; //[sp+7h] [bp-9h]@1 _int64 v2; // [sp+8h] [bp-8h]@1 v2 = *MK_FP(_FS_, 40LL); read(0, &buf, 0x100uLL); return *MK_FP(_FS_, 40LL) ^ v2; }
时间: 2024-04-01 16:30:58 浏览: 51
首先需要注意的是,该代码存在缓冲区溢出漏洞,因为只为 buf 分配了 1 字节的空间,而 read 函数却可以读取 0x100 字节的数据,因此可能会导致缓冲区溢出。在需要覆盖 ebp 的情况下,需要填充的字节数应该为 8 个字节,因为在 64 位程序中,ebp 和 rsp 的大小均为 8 字节。攻击者可以通过填充 8 个字节的数据,将 ebp 覆盖掉,从而改变程序的执行流程。因为 ebp 是用来保存函数调用过程中的堆栈信息的,因此改变 ebp 的值可以使程序跳转到攻击者指定的地址,从而执行任意代码。
相关问题
下面的代码为一个64位程序的反汇编代码,在需要覆盖ebp的情况下,需要填充多少个字节到buf的缓冲区,才能改变程序的执行流程? _int64 stack_overflow() { char buf; //[sp+7h] [bp-9h]@1 _int64 v2; // [sp+8h] [bp-8h]@1 v2 = *MK_FP(_FS_, 40LL); read(0, &buf, 0x100uLL); return *MK_FP(_FS_, 40LL) ^ v2; } 8个 9个 17个 18个
根据反汇编代码,可以看到函数内部定义了一个 char 类型的 buf 变量,它的大小为 1 字节。在该函数内部,read 函数的第二个参数是指向 buf 的指针,且读取的字节数为 0x100。由于 buf 的大小只有 1 字节,而读取的字节数为 0x100 字节,因此会导致栈溢出的问题。
为了改变程序的执行流程,需要覆盖函数的返回地址,而该地址保存在 ebp+4 的位置上。由于 buf 的大小为 1 字节,因此需要填充 17 个字节才能覆盖 ebp+4 的位置。因此,答案为 17 个字节。
1.下为一段C语言源程序,其中,编译器为authenticated变量分配4个字节空间, 为buffer变量分配8个字节空间。程序执行完图中所标记的“strcpy(buffer,password);语句时,堆栈的布局如下图b所示(注意:低字节数据保存在低地址,例如字符串 “123”在堆栈中存储状态为“0x00333231”)。 #define PASSWORD "1234567” int verify password(char *password) { int authenticated; char buffer[8]; authenticated=strcmp(password,PASSWORD);//两者相同则返回0 strcpy (buffer, password) ; return authenticated; } int main () { int valid flag=0; char password[1024]; while(1) { printf("please 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”) ; } } } 图a 验证口令演示程序 buff[0]-buff[3] 低地址 buff[4]-buf[7] authenticated main函数EBP main函数返回地址 高地址 图b调用子程序时的堆栈布局 请分析程序及堆栈特征,回答如下问题: (1)当从键盘输入“1234567”时,程序执行完图a 中所标记的strcpy 语句之后,堆栈 会如何变化(请画图说明)?此时程序的最终执行结果将会是什么? (2)当满足什么条件时,可以在不知道真实口令的情况下绕过口令验证功能?为什么?
(1) 当从键盘输入“1234567”时,程序执行完图a中所标记的strcpy语句之后,堆栈会如下图所示变化:
```
buff[0]-buff[3] 低地址
0037 0036 0035 0034
0x31 0x32 0x33 0x34
buff[4]-buff[7]
0038 0039 0040 0041 0042 0043 0044 0045
0x35 0x36 0x37 0x00 ? ? ? ?
authenticated
0046 0047 0048 0049
0x00 0x00 0x00 0x00
main函数EBP
0050 0051 0052 0053
? ? ? ?
main函数返回地址
0054 0055 0056 0057
? ? ? ?
高地址
```
此时,程序的最终执行结果将会是口令验证通过,输出“congratulation. You have passed the verification”。
(2) 当输入的口令长度超过8个字符时,可以在不知道真实口令的情况下绕过口令验证功能。因为buffer数组只能存储8个字符,如果输入的口令长度超过8个字符,会导致strcpy函数将多余的字符写入到authenticated变量和main函数的返回地址所在的内存空间,从而覆盖了这些关键数据,导致程序出现未知的错误,可能会使得程序出现异常,或者跳转到攻击者指定的地址执行恶意代码。这种漏洞称为栈溢出漏洞,是一种常见的安全漏洞。
阅读全文