2011-09-08 16 views
18

मैं एक बहुत ही सरल बफर ओवरफ़्लो हमला निष्पादित करने का प्रयास कर रहा हूं। मैं इसके लिए बहुत नौसिखिया हूँ। तो, अगर इस सवाल का बेवकूफ है, कृपया मुझे :-)बफर ओवरफ़्लो अटैक

बहाना कोड:

#include<stdio.h> 
#include<stdlib.h> 

int i, n; 

void confused(int i) 
{ 
printf("**Who called me? Why am I here?? *** %x\n ", i); 
} 

void shell_call(char *c) 
{ 
printf(" ***Now calling \"%s\" shell command *** \n", c); 
system(c); 
} 

void victim_func() 
{ 
int a[4]; 
printf("Enter n: "); scanf("%d",&n); 
printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~"); 
for (i = 0;i <n ;i++) 
    printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]); 
printf("\nEnter %d HEX Values \n", n); 

// Buffer Overflow vulnerability HERE! 

for (i=0;i<n;i++) scanf("%x",&a[i]); 
    printf("Done reading junk numbers\n"); 
} 

int main() 
{ 
victim_func(); 
printf(“\n done”); 
return 0; 
} 

जब मैं objdump का उपयोग समारोह पतों प्राप्त करने के लिए, मैं निम्नलिखित है:

main(): 0x804854d 
Address of main() where printf() is called: 0x8048563 
victim_func(): 0x8048455 
confused(): 0x8048414 

अब, मैं चाहता हूं कि वहां बफर को बहने से पीड़ित_फनक() से 'भ्रमित()' फ़ंक्शन पर कूदना है, और भ्रमित() के पते पर वापसी पता ओवरराइट करना है। और मैं उलझन में() मुख्य रूप से printf() कथन से वापस लौटना चाहता हूं, और सामान्य रूप से बाहर निकलना चाहता हूं। तो, मैं निम्नलिखित इनपुट प्रदान

Enter n: 7 
Enter 7 HEX values: 
1 
2 
3 
4 
5 
8048414 (This is to jump to confused) 
8048563 (this is to jump to printf() in main) 

हालांकि, इसे वापस victim_func लिए उतर रहा है() कार्यक्रम प्रिंट कि printf बयान से "हो गया" और प्रिंट, "Enter n:"

मैं क्या कर रहा हूँ गलत? किसी भी तरह की सहायता का स्वागत किया जाएगा!

पीएस: मुझे यकीन नहीं है कि मैंने सही सवाल रखा है या नहीं। यदि कोई और जानकारी की आवश्यकता है, तो कृपया मुझे बताएं।

+5

वास्तव में, यह स्कूल में एक असाइनमेंट है! – Ashwin

+0

यदि यह वास्तव में होमवर्क है, तो कृपया इसे इस तरह टैग करें। – NPE

+7

@VJo मुझे लगता है कि यह एक महान शैक्षणिक कार्य है - मैं इसे स्वयं करने का प्रयास कर रहा हूं: इसे कोड के असेंबलर कार्यान्वयन के साथ गहरी समझ और प्रत्यक्ष प्रयोग की आवश्यकता है। सफेद टोपी भी इन विचारों को समझने की जरूरत है। – Elemental

उत्तर

8

एक बफर ओवरफ़्लो हमला इससे कहीं अधिक जटिल है। सबसे पहले आपको इसे करने के लिए असेंबलर को समझने की आवश्यकता है। प्रोग्राम और फ़ंक्शन को अलग करने के बाद आप लक्षित करना चाहते हैं, जब आप उस फ़ंक्शन को निष्पादित करते समय स्टैक लेआउट निर्धारित करने की आवश्यकता होती है। यहां विज़ुअल स्टूडियो का उपयोग करके एक बफर ओवरफ़्लो का नमूना है लेकिन सिद्धांत समान है।

#include "stdafx.h" 
#include <math.h> 

volatile double test; 

double function3() 
{ 
    test++; 
    return exp(test); 
} 

double function2() 
{ 
    return log(test); 
} 

double function1() 
{ 
    int a[5] = {0};   
    a[7] = (int)&function3; 
    return exp(function2()); 

} 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    double a = function1(); 
    test = a; 
    return a; 
} 

धन्यवाद disassembly के लिए हम जानते हैं कि function1 में एक से पहले जहां समारोह स्टैक फ्रेम सूचक बचाया आवंटित किया जाता है। उसके बाद का मूल्य वापसी का पता है जहां फ़ंक्शन 1 को समाप्त होने पर जाना चाहिए।

00401090 55    push  ebp <- we save the stack pointer 
00401091 8B EC   mov   ebp,esp 
00401093 83 EC 1C   sub   esp,1Ch <- save space to allocate a[5] 
00401096 B8 CC CC CC CC mov   eax,0CCCCCCCCh 
0040109B 89 45 E4   mov   dword ptr [ebp-1Ch],eax <- crt debug init a[5] 
0040109E 89 45 E8   mov   dword ptr [ebp-18h],eax 
004010A1 89 45 EC   mov   dword ptr [ebp-14h],eax 
004010A4 89 45 F0   mov   dword ptr [ebp-10h],eax 
004010A7 89 45 F4   mov   dword ptr [ebp-0Ch],eax 
004010AA 89 45 F8   mov   dword ptr [ebp-8],eax 
004010AD 89 45 FC   mov   dword ptr [ebp-4],eax 

इस से हम अगर हम ऊपर लिख एक [7] एक अलग पते के साथ, समारोह मुख्य करने के लिए नहीं है, लेकिन जो कुछ भी पता के साथ हम में लिखा वापस आ जाएगी निष्कर्ष निकाल सकते हैं एक [7]।

उम्मीद है कि इससे मदद मिलती है।

+0

रोगी स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। यही वह जगह है जहां मैं फंस गया हूँ! सरणी के 5 शब्दों को स्टोर करने के लिए हमें 1Ch शब्दों को आवंटित करने की आवश्यकता क्यों है? क्या आप यहां ढेर संरचना पर विस्तृत जानकारी दे सकते हैं? – Ashwin

+0

और, यह मेरे अलग-अलग मुख्य दिनचर्या का एक हिस्सा है। '0x0804855b : \t उप $ 0x4,% esp' ' 0x0804855e : \t कॉल 0x8048455 '' 0x08048563 : \t movl $ 0x804872e, (% esp) '' 0x0804856a : \t कॉल 0x8048364 <[email protected]> ' तो, मैं उलझन में, 0x8048563 पर मुख्य() पर लौट रहा हूं। सही स्मृति स्थान में वापसी पता लगाने में कोई समस्या नहीं है। और, मुख्य() "हो गया" प्रिंट करके फिर से शुरू होता है। लेकिन इस बिंदु पर, यह पीड़ित_फनक() पर वापस जाता है और प्रिंट करता है "एंटर एन:" यही वह है जिसे मैं समझ नहीं पा रहा हूं। – Ashwin

1

सबसे पहले ऐसा लगता है कि आपको अपने नमूना इनपुट में नंबर 5 दर्ज नहीं करना चाहिए। आपकी सरणी को एक घोषित किया गया है [4] इस प्रकार तत्वों को 0-3 से अनुक्रमित किया गया है - इसलिए आपका हमला इनपुट मेरे लिए गलत लगता है।

  • sizof (int) == sizeof (स्मृति पता)
  • विकास और वातावरण की व्यवस्था की दिशा ढेर कार्यान्वयन:

    यह भी मुझे लगता है अपने कार्यक्रम वास्तुकला के बारे में कई बात मानता है कि

यदि इनमें से एक धारणा असत्य है तो यह कभी भी काम नहीं करेगा।

यह एक बहुत ही कठिन काम कार्य असाइनमेंट की तरह लगता है।

कोड के नियंत्रण प्रवाह को बदलने से बफर ओवरफ्लो हमलों के आसान उदाहरण हैं।उदाहरण के लिए आप डेटा के दूसरे हिस्से को ओवरराइट कर सकते हैं जिसे उपयोगकर्ता से सुरक्षित किया जाना चाहिए (जैसे सुरक्षा सेटिंग)

+2

सरणी की सीमाओं से परे इंडेक्सिंग ठीक है कि इस तरह के हमले कैसे काम करते हैं। और ऐसे हमले हमेशा बहुत मंच पर निर्भर होते हैं; वे इस बात पर निर्भर करते हैं कि ढेर कैसे लगाया जाता है, और आमतौर पर कुछ असेंबलर शामिल होते हैं।सामान्य समाधान मशीन कोड डालना होगा जो बफर में कुछ सही करता है, फिर बफर के पते के साथ स्टैक पर वापसी पता को प्रतिस्थापित करें। –

0

आपने हमें [i के पते के साथ प्रोग्राम का आउटपुट नहीं दिखाया ]। मुझे संदेह है कि कंपाइलर 16 तक स्टैक पर डेटा को संरेखित करने जैसा कुछ कर रहा है। यह आपकी अपेक्षा से रिटर्न पते पर बहुत आगे हो सकता है।

1

अब, क्या मैं चाहता हूँ() बफर वहाँ के पते पर वापसी पता बह निकला, और ओवरराइट करके समारोह 'भ्रमित()' victim_func से जाने के लिए है भ्रमित() ...

आधुनिक लिनक्स प्लेटफ़ॉर्म पर, आपको यह सुनिश्चित करने की भी आवश्यकता होगी कि परीक्षण के लिए दो सुरक्षा सुविधाएं बंद हैं। सबसे पहले एनएक्स-स्टैक्स में, और दूसरा स्टैक प्रोटेक्टर है।

एनएक्स-स्टैक्स को बंद करने के लिए, -Wl,z,execstack (-Wl,z,noexecstack के विपरीत) का उपयोग करें। स्टैक प्रोटेक्टर को बंद करने के लिए, -fno-stack-protector का उपयोग करें (-fstack-protector या -fstack-protector-all के विपरीत)।

एक तीसरी सुरक्षा है जिसे आपको बंद करने की आवश्यकता हो सकती है। वह सुरक्षा FORTIFY_SOURCE है। FORTIFY_SOURCE memcpy और strcpy जैसे उच्च जोखिम कार्यों के "सुरक्षित" रूपों का उपयोग करता है। कंपाइलर सुरक्षित भिन्नता का उपयोग करता है जब यह गंतव्य बफर आकार को कम कर सकता है। यदि प्रतिलिपि गंतव्य बफर आकार से अधिक हो जाएगी, तो प्रोग्राम abort() पर कॉल करता है। FORTIFY_SOURCE को अक्षम करने के लिए, प्रोग्राम को -U_FORTIFY_SOURCE या -D_FORTIFY_SOURCE=0 से संकलित करें।

सुरक्षा सुविधाओं को डिफ़ॉल्ट रूप से चालू किया जाता है क्योंकि अतीत में इतनी सारी समस्याएं हुई हैं। आम तौर पर, यह एक अच्छी बात है क्योंकि यह कई समस्याओं को रोकता है (जैसे आप प्रयोग कर रहे हैं)।

संबंधित मुद्दे