[英]Simple Buffer Overflow in C
因此,我正在做一个练习,尝试通过使用缓冲区溢出更改相关变量来使以下程序输出“欢迎使用溢出”。 这是代码。
#include <stdio.h>
int main(){
int a = 10;
char c = 'X';
char array2[] = {'A', 'B', 'C', 'D', 'E', 'F'};
char array[4];
printf("please enter: \n");
scanf("%s", array);
printf("c = %c\n", c);
printf("a = %d\n", a);
printf("array = %s\n", array);
printf("array2 = %s\n", array2);
printf("array[2] = %x\n", *(array + 2));
printf("array2[3] = %x\n", array2[3]);
if (c == 'X' && a == 11999 && *(array + 2) == 0x99 - 0x34 && array2[3] == 'X') {
printf("Welcome to overflow!\n");
} else {
printf("This is normal output!\n");
}
}
我需要的是c == 'X' && a == 11999 && *(array + 2) == 0x99 - 0x34 && array2[3] == 'X'
。
所以我得到了每个变量,除了我想要的以外,其他都是我想要的。
通过输入以下内容,我可以更改它们。 我输入“ XXeXXXXXXXXB”,这将array[2]
更改为65 ,将array2[3]
更改为X ,将c
更改为“ X”,但我无法更改的变量为“ a”。 通过使输入的第12炭a
它改变乙 a
为“66”,这是炭“B”的相应的十进制数。 如果输入第13个char,则变量a
将更改为char * 257的十进制等值。由于a
必须为11999,所以我迷路了。
我尝试将11999除以257,但得出的结果是46.6,因此没有该值的char,我什至尝试将最接近46.6的char设为'。 和'/',但是a
太大或太小。
为了将a
更改为11999,我可以输入第12个和第13个字符是什么? 同样,如果您不想给我平淡无奇的答案,我将感谢您指出正确方向的观点。
这是一个有趣的练习。 由于您正在调用未定义的行为,因此对您的问题的回答并不完全是一个答案,因此必须逐案评估。 这种攻击甚至可能在某些计算机上不起作用。
首先,对于这种测试,您应该使用printf来查看数据在哪里:
printf("a is at %p\n", &a);
printf("array is at %p\n", array);
...
这应该使您了解需要偏移多少个字节。 接下来,确定您是在使用小端还是大端系统。 如果您在使用little-endian,那么11999是0xDF2E0000,如果您使用big-endian,则它是向后的。
因此,假设您的程序是在小端系统上进行的,那么假设所有数据在内存中的正确顺序都可以正常工作,并且整数是4个字节,则需要字符串“-” +(0x99-0x34)+“- ... X..X“ + 0xDF2E0000
编辑:此字符串的原因如下:
您可以通过添加以下内容进行测试:
#include <string.h>
char str[] = {16};
sprintf(str, "--%c-...X..X%c%c\0\0", 0x99 - 0x34, 0xDF, 0x2E);
memcpy(array, str, 14);
printf("The string is: \"%s\"", str);
代替您的scanf。 显然,您可以找出与这些值关联的字符并将其粘贴,但这是获取正确数据的最快方法。
当然,这取决于系统的更改,上面的代码甚至可能无法在您的计算机上运行。 这仍然是很真实的事情,并且很好地说明了为什么总是限制阅读和书写的字符数,并确保使用正确的结尾字符。
如果我错过了上述任何假设/因素,如果有人让我知道,我将不胜感激。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.