2015-08-08 7 views
5

मैं किसी प्रोग्राम के भीतर से शेलकोड निष्पादित करना सीखने की कोशिश कर रहा हूं, लेकिन मुझे चलाने के लिए सबसे बुनियादी कोड भी नहीं मिल सकता है। निम्नलिखित कोड टर्मिनल से बाहर निकलने के लिए बस बाहर निकलना चाहिए:फ़ंक्शन के रूप में एक वर्ण स्ट्रिंग कास्टिंग

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <sys/mman.h> 

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80"; 

int main() { 
    int (*func)(); 
    func = (int (*)())exitcode; 
    (int)(*func)(); 
    return 0; 
} 

लेकिन मुझे जो कुछ मिलता है वह एक सीगफॉल्ट है। जीडीबी का कहना है कि यह तब हो रहा है जब प्रोग्राम निकास कोड के स्मृति स्थान [at (int) (* func)(); ], लेकिन मुझे यकीन नहीं है कि यह समस्या क्यों पैदा कर रहा है। मैं 64-बिट लिनक्स मिंट ओएस चला रहा हूं। कोई भी मदद बहुत ही सराहनीय होगी।

+0

यदि शेलकोड की स्मृति गैर निष्पादन योग्य क्षेत्र में है तो यह काम नहीं करेगा। अधिकांश आधुनिक ऑपरेटिंग सिस्टम शायद इसकी अनुमति नहीं देंगे। आपको यह भी सुनिश्चित करना चाहिए कि आपके आर्किटेक्चर के लिए शेलकोड सही है। –

+1

क्या सी या सी ++ के लिए है? अर्थशास्त्र और संभावित उत्तर भिन्न हो सकते हैं। – Olaf

+0

फ़ंक्शन पॉइंटर पर ऑब्जेक्ट पॉइंटर कास्टिंग करना _undefined behaviour_ है। कुछ भी हो सकता है – Olaf

उत्तर

6

आधुनिक ऑपरेटिंग सिस्टम मेमोरी सुरक्षा का उपयोग करते हैं। मेमोरी के पेजों में फाइलों की तरह एक्सेस अधिकार हैं: पठनीय, लिखने योग्य, निष्पादन योग्य। आपके प्रोग्राम का आपका डेटा सेगमेंट आम तौर पर एक गैर-निष्पादन योग्य पृष्ठ में होता है, जो इसे सीगफॉल्ट में निष्पादित करने का प्रयास करता है।

आप लिनक्स पर अपने कार्यक्रम से गतिशील रूप से लिखा बाइनरी कोड निष्पादित करने के लिए चाहते हैं, आप पहली बार है कि आप करने के लिए लिख सकते हैं एक पेज mmap() का उपयोग कर मैप करने के लिए है, तो अपने कोड जगह वहाँ, और फिर पढ़ा के लिए इसे बदल ही, निष्पादनmprotect() का उपयोग कर। तब आप वहां कूद सकते हैं।

विवरण के लिए आप उदाहरण के लिए read this article कर सकते हैं।

EDIT: यदि यह सुरक्षा उल्लंघनों के बारे में है, तो ध्यान दें कि स्टैक आम तौर पर आज भी गैर निष्पादन योग्य नहीं है ... इसलिए ये सभी पुराने "हैकिंग ट्यूटोरियल" अब और काम नहीं करेंगे। यदि आप नई तकनीकों में रुचि रखते हैं, तो वापसी उन्मुख प्रोग्रामिंग पढ़ें।

0

आपका shellcode है:

mov $0x1,%al 
xor %ebx,%ebx 
int $0x80 

दो समस्याएं हैं:

  1. syscall 0x1 64-बिट पर एक sys_write है (लेकिन 32-बिट पर यह sys_exit है)
  2. आप आवंटित करने चाहिए % रैक्स के लिए,% al नहीं। % रैक्स में उच्च बिट्स में बचे हुए होंगे।
4

कोड निष्पादन योग्य कोड के रूप में चिह्नित किया जाना चाहिए। ऐसा करने का एक तरीका यह है कि इस बाइनरी मशीन कोड को निष्पादन योग्य बफर में कॉपी करना है।

#include <unistd.h> 
#include <sys/mman.h> 
#include <string.h> 

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80"; 

int main(int argc, char **argv) 
{ 
    void *buf; 

    /* copy code to executable buffer */  
    buf = mmap (0,sizeof(exitcode),PROT_READ|PROT_WRITE|PROT_EXEC, 
       MAP_PRIVATE|MAP_ANON,-1,0); 
    memcpy (buf, exitcode, sizeof(code)); 

    /* run code */ 
    int i = ((int (*) (void))buf)(); 
    printf("OK. returned: %d", i); 
return 0; 
} 
0

मुझे यह समस्या थी और इसे हल करने के लिए बहुत कुछ खोजा गया। (ढेर सुरक्षा अक्षम करने के लिए और यह निष्पादन योग्य बनाने के)

आप अपने सी कोड को संकलित करने के लिए इस कोड का उपयोग करना चाहिए:

gcc -fno-stack-protector -z execstack -o hello hello.c 

काली 32/64 बिट में परीक्षण किया गया। अब कोई segfault नहीं।

शुभकामनाएं

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