मैं प्रवाह शोषण पर एक बफर प्रदर्शित करने के लिए एक प्रयोगशाला के माध्यम से अपना काम कर रहा हूं। मेरे पास यह काम कर रहा है लेकिन एक ऐसा क्षेत्र है जिसे मैं समझ नहीं पा रहा हूं कि मुझे उम्मीद है कि कोई मेरे लिए समझा सकता है।

यह शोषण के साथ कोड है:

/* Vunlerable program: stack.c */
/* You can get this program from the lab’s website */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(char *str)
{
  char buffer[24];
  /* The following statement has a buffer overflow problem */
  strcpy(buffer, str); ➀
  return 1;
}
int main(int argc, char **argv)
{
  char str[517];
  FILE *badfile;
  badfile = fopen("badfile", "r");
  fread(str, sizeof(char), 517, badfile);
  bof(str);
  printf("Returned Properly\n");
  return 1;
}

प्रयोगशाला का एक चरण बफर को आवंटित स्मृति के आकार का निर्धारण करना है [24]। ऐसा करने के लिए मैंने जो किया है वह bof फ़ंक्शन पर gdb चलाता है और मैं देख सकता हूं कि मेरे सिस्टम पर आवंटित स्मृति 0x20 है जो 32 बिट्स है।

अगर मैं बफर का आकार बदलता हूं तो मैं जीडीबी चला सकता हूं और आवंटित मेमोरी स्लॉट ढूंढ सकता हूं। लेकिन क्या मुझे यह बताने में सक्षम होना चाहिए कि जीडीबी के बिना बफर [24] को कितनी मेमोरी आवंटित की जाएगी? अगर मैं बफर में बदल जाता हूं [8] तो क्या मुझे एक नज़र में पता होना चाहिए कि 32 बिट सिस्टम पर मेमोरी ब्लॉक क्या है, या क्या यह सिस्टम पर भिन्न होता है? और अगर मुझे पता होना चाहिए तो क्या कोई समझा सकता है कि कैसे।

0
Peck3277 1 अप्रैल 2020, 12:29

1 उत्तर

सबसे बढ़िया उत्तर

यह लक्ष्य मंच, संकलक और संकलन झंडे पर निर्भर करता है।

उदाहरण के लिए, डिबग मोड में GCC 7.2 x86 (-O0) स्टैक फ़्रेम को 16-बाइट सीमा पर संरेखित करता है और एक फ़्रेम पॉइंटर (ebp) आवंटित करता है।

उदाहरण: (godbolt link)

bof(char*):
        push    ebp                   ; -4
        mov     ebp, esp           
        sub     esp, 40               ; -40
        sub     esp, 8                ; -8
        push    DWORD PTR [ebp+8]     ; -4
        lea     eax, [ebp-32]         ; 32 bytes to top of stack frame
        push    eax                   ; -4
        call    strcpy                ; stack is aligned to 16 bytes (-64)
        add     esp, 16
        mov     eax, 1
        leave
        ret

ऑप्टिमाइज़ेशन के साथ (-O2) फ़्रेम पॉइंटर को छोड़ दिया जाता है, लेकिन स्टैक अभी भी 16 बाइट्स पर संरेखित होता है (गॉडबोल्ट लिंक):

bof(char*):
        sub     esp, 52               ; -52
        push    DWORD PTR [esp+56]    ; -4
        lea     eax, [esp+20]         ; 36 bytes to top of stack frame
        push    eax                   ; -4
        call    strcpy                ; stack is aligned to 16 bytes (-64)
        mov     eax, 1
        add     esp, 60
        ret

ज़बरदस्ती 4-बाइट स्टैक संरेखण (-O2 -mpreferred-stack-boundary=2) (godbolt link) के साथ:

bof(char*):
        sub     esp, 24               ; -24
        push    DWORD PTR [esp+28]    ; -4
        lea     eax, [esp+4]          ; 24 bytes to top of stack frame
        push    eax                   ; -4
        call    strcpy
        mov     eax, 1
        add     esp, 32
        ret

स्टैक रक्षक के साथ (-O2 -fstack-protector-all) (godbolt link):

bof(char*):
        sub     esp, 52                      ; -52
        mov     eax, DWORD PTR gs:20
        mov     DWORD PTR [esp+36], eax      ; stack check value at -16 (-52+36)
        xor     eax, eax
        push    DWORD PTR [esp+56]           ; -4
        lea     eax, [esp+16]                ; 40 bytes to top of stack frame, leaving exactly 24 bytes to check value
        push    eax
        call    strcpy
        add     esp, 16
        mov     edx, DWORD PTR [esp+28]
        xor     edx, DWORD PTR gs:20
        jne     .L5
        mov     eax, 1
        add     esp, 44
        ret
.L5:
        call    __stack_chk_fail

अन्य कंपाइलरों के पूरी तरह से अलग परिणाम हो सकते हैं।

वास्तविक जीवन में, निर्देशों का विश्लेषण करके और फ़ंक्शन के रिटर्न पते पर बाइट्स को गिनकर असेंबली मोड में एक बफर ओवरफ्लो का शोषण किया जाता है, इसलिए इससे कोई फर्क नहीं पड़ता कि स्रोत कोड क्या था या इसे कैसे संकलित किया गया था (यह जानकारी अक्सर वैसे भी अनुपलब्ध होती है)।

1
rustyx 1 अप्रैल 2020, 13:48