मैं एक शेलकोड बनाने की कोशिश कर रहा हूं जो लिनक्स x86_64 असेंबली में '/ बिन/श' खोल पैदा करता है, और जब मैं इसे निष्पादन योग्य के रूप में निष्पादित करता हूं तो यह ठीक काम करता है। समस्या यह है कि जब मैं कोड के बाइनरी को डंप करता हूं और इसे एक स्ट्रिंग के रूप में डालता हूं तो मुझे त्रुटि मिलती है:

'विभाजन दोष (कोर नहीं चला '

    global _start

    section .text

    _start:

    push    59   ;sys_execve
    pop rax
    xor rdi,    rdi
    push rdi
    mov rdi,    0x68732F2f6e69622F ;/bin//sh in reverse
    push rdi
    mov rdi,    rsp ;pointer to the /bin//sh
    xor rsi,    rsi ;NULL
    xor rdx,    rdx ;NULL
    syscall

बाइनरी के बिना सी में शेलकोड:

  #include <stdio.h>

  char sh[]="\x6a\x3b\x58\x48\x31\xff\x57\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x0f\x05 ";

  void main(int argc, char **argv)
 {
     int (*func)();
     func = (int (*)()) sh;
     (int)(*func)();
 }

कमांड मैं अपना शेलकोड जनरेट करता था:

nasm -felf64 shellcode.nasm -o shellcode.o
ld shellcode.o -o shellcode

मैं जिस प्रोग्राम का शोषण कर रहा हूं उसे उत्पन्न करने के लिए उपयोग किया जाने वाला आदेश:

gcc -fno-stack-protector -z execstack shellcode.c

स्ट्रेस ./ शेलकोड आउटपुट:

    execve("./shellcode", ["./shellcode"], 0x7ffe19f431f0 /* 59 vars */) = 0
brk(NULL)                               = 0x5651f32c3000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=96319, ...}) = 0
mmap(NULL, 96319, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff0d7a8d000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff0d7a8b000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff0d748d000
mprotect(0x7ff0d7674000, 2097152, PROT_NONE) = 0
mmap(0x7ff0d7874000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7ff0d7874000
mmap(0x7ff0d787a000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ff0d787a000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7ff0d7a8c4c0) = 0
mprotect(0x7ff0d7874000, 16384, PROT_READ) = 0
mprotect(0x5651f168d000, 4096, PROT_READ) = 0
mprotect(0x7ff0d7aa5000, 4096, PROT_READ) = 0
munmap(0x7ff0d7a8d000, 96319)           = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x5651f168e020} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)
1
ebro 18 मई 2019, 17:19

1 उत्तर

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

gcc -fno-stack-protector -z execstack shellcode.c shellcode नाम की कोई फाइल नहीं बनाता। यह a.out बनाता है क्योंकि आपने -o का उपयोग नहीं किया।

इसलिए strace ./shellcode चलाने से आपके द्वारा NASM + ld के साथ निर्मित बाइनरी चलाई जाएगी। लेकिन आपके द्वारा दिखाया गया स्ट्रेस आउटपुट स्थिर निष्पादन योग्य से मेल नहीं खाता है। हो सकता है कि यह पहले के gcc आह्वान से था जहां आप भूल गए थे -z execstack

अपने स्रोत के अपने वर्तमान संस्करण से gcc के साथ आपके द्वारा बनाई गई फ़ाइल को चलाने के लिए चलाएं strace ./a.out


यदि आप execve को गलत आर्ग पास कर रहे थे, तो strace इसे -EFAULT लौटाते हुए दिखाएगा। लेकिन इसके बिना सिर्फ segfaulting का मतलब है कि आपके द्वारा चलाया गया निष्पादन योग्य गैर-निष्पादन योग्य पृष्ठ पर जाने का प्रयास कर रहा था। यह -zexecstack के बिना बाइनरी बिल्ड से पूरी तरह मेल खाएगा।

3
Peter Cordes 18 मई 2019, 16:23