[英]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.