2013-02-09 14 views
9

के लिए अनुमति देने के लिए संकलित सी मैं बफर ओवरफ्लो के बारे में सीख रहा हूं और एक बनाने की कोशिश कर रहा हूं।बफर ओवरफ्लो

#include <stdio.h> 

char *secret = "password"; 

void go_shell() { 
    char *shell = "/bin/sh"; 
    char *cmd[] = { "/bin/sh", 0 }; 
    setreuid(0); 
    execve(shell,cmd,0); 
} 

int authorize() { 
    char password[64]; 
    printf("Enter Password: "); 
    gets(password); 
    if (!strcmp(password,secret)) { 
     return 1; 
    } 
    else { 
     return 0; 
    } 
} 

int main() { 
    if (authorize()) { 
     printf("login successful\n"); 
     go_shell(); 
    } else { 
     printf("Incorrect password\n"); 
    } 
    return 0; 
} 

मैं जीसीसी के साथ इस संकलन और उसके बाद gdb

मैं पासवर्ड और कार्यक्रम दुर्घटनाओं के रूप में लगभग 100 'ए' s दर्ज में इसे चलाने: मैं इस कोड है।

समस्या नहीं रजिस्टर 0x4141414141414141

मैं इस googled और gcc को -fno-stack-protector झंडा जोड़ा है, जिसकी अनुमति RBP 0x4141414141414141 लेकिन कुछ भी बाकी को ओवरराइट किया जा करने के लिए करने के लिए ओवरराइट किया जाता है।

मैं सोच रहा था कि कोड को संकलित करने का कोई तरीका था ताकि आरआईपी ओवरराइट किया जा सके।

+0

क्या आप लिनक्स का उपयोग कर रहे हैं? मुझे लगता है कि आपको कुछ ध्वज सेट करने की भी आवश्यकता है। मैक ओएसएक्स का उपयोग कर – nhahtdh

+0

। कोई विचार क्या ध्वज है? – carloabelli

+0

मैक ओएसएक्स के बारे में मुझे नहीं पता - शायद उबंटू से काफी अलग होने जा रहा है (क्षमा करें, मैंने वास्तव में यह उबंटू पर किया था, लिनक्स नहीं)। – nhahtdh

उत्तर

3

यदि आप -fno-stack-protector के साथ संकलित करते हैं तो आपका कोड पहले से ही वही करता है जो आप चाहते हैं। GDB में 0x4141414141414141 के मान के साथ RIP को देखने का कारण यह है कि RIP अद्यतन होने से पहले एक सामान्य सुरक्षा गलती फेंक दी जाती है। (यदि कोई पृष्ठ गलती होती है, तो जीपीएफ हैंडलर आमतौर पर पृष्ठ को स्वैप से लोड करता है और असफल निर्देश से शुरू करके निष्पादन को फिर से शुरू करता है।)

+0

मदद के लिए धन्यवाद, लेकिन मैं सोच रहा था कि क्या उस जीपीएफ को बंद करने का कोई तरीका था ताकि आरआईपी को '0x4141414141414141' पर सेट किया जा सके क्योंकि यह उस ट्यूटोरियल में होता है जो मैं उपयोग कर रहा हूं। – carloabelli

+0

@ cabellicar123 आप जीपीएफ से नहीं बच सकते हैं जब तक कि आप उस पते पर निष्पादन योग्य पृष्ठ नहीं बनाते। बस अपने ट्यूटोरियल के साथ आगे बढ़ें। शायद अगला कदम विशेष रूप से तैयार किए गए पासवर्ड की आपूर्ति करेगा जो कोड को वैध पते पर कूद देगा। – nwellnhof

+0

आपकी मदद के लिए बहुत बहुत धन्यवाद! – carloabelli

1

एक्स 32 पर ईआईपी 0 × 41414141 का दुर्घटना होने का कारण यह है कि जब प्रोग्राम पॉप पहले सहेजे गए ईआईपी मूल्य को स्टैक से बाहर और वापस ईआईपी में सीपीयू फिर मेमोरी एड्रेस 0 × 41414141 पर निर्देश निष्पादित करने का प्रयास करता है जो एक सेगफॉल्ट का कारण बनता है। (इसे पाठ्यक्रम के निष्पादन से पहले पृष्ठ प्राप्त करना होगा)

अब, x64 निष्पादन के दौरान जब प्रोग्राम पहले से सहेजे गए आरआईपी मान को आरआईपी रजिस्टर में वापस चलाता है तो कर्नेल मेमोरी एड्रेस 0 × 4141414141414141 पर निर्देशों को निष्पादित करने का प्रयास करता है। सबसे पहले, कैननिकल फॉर्म एड्रेसिंग के कारण, किसी वर्चुअल एड्रेस के 48 से 63 बिट्स बिट 47 की प्रतियां (साइन एक्सटेंशन के समान तरीके से) होनी चाहिए, या प्रोसेसर अपवाद उठाएगा। यदि यह कोई मुद्दा नहीं था- कर्नेल पृष्ठ गलती हैंडलर का आविष्कार करने से पहले कर्नेल अतिरिक्त चेक करता है क्योंकि अधिकतम उपयोगकर्ता स्थान पता 0x00007FFFFFFFFFF है।

पुन: संक्षेप में, x32 आर्किटेक्चर में पता पृष्ठ पेज गलती हैंडलर को "सत्यापन" के बिना पारित किया गया है जो कर्नेल को प्रोग्राम segfault भेजने के लिए ट्रिगर करने वाले पृष्ठ को लोड करने का प्रयास करता है लेकिन x64 अब तक नहीं मिलता है।

टेस्ट यह, साथ 0 × 0000414141414141 और आप उम्मीद मूल्य गिरी पास से prechecks और उसके बाद पृष्ठ दोष हैंडलर x32 मामले की तरह शुरू हो जाती है के बाद से आरआईपी में रखा गया है (देखेंगे अधिलेखित आरआईपी जो ज़ाहिर है, तो कार्यक्रम को दुर्घटनाग्रस्त होने का कारण बनता है)।

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