ReverseEngineering – Telegram
ReverseEngineering
1.24K subscribers
40 photos
10 videos
55 files
666 links
Download Telegram
بخش ششم بافر اورفلو


درک دقیق کرش و ساختار فریم تابع در استک

در این بخش میخایم ببینیم وقتی بافر اورفلو باعث کرش میشه دقیقا در پشت‌ صحنه چه اتفاقی میوفته باید بعد از این قسمت
بفهمیم چرا بازنویسی داده در استک باعث تغییر آدرس برگشت میشه
فریم تابع چه اجزایی داره
و چطور میشه این اجزا رو با gdb دید و تحلیل کرد

وقتی یک تابع در C صدا زده میشه سیستم برای اون تابع فضایی در استک درست میکنه به این فضا میگیم فریم تابع هر فریم شامل این بخش‌ هاست

متغیرهای لوکال تابع

مقادیر پارامترها

saved RBP یا base pointer
برای برگشت

saved return address
که بعد از تموم شدن تابع بهش برمیگرده


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


این کد کمک میکنه تا فریم تابع و کرش رو ببینیم و در gdb تجزیه ش کنیم

#include <stdio.h>
#include <string.h>

void crash(char *input) {
char buffer[16];
printf("address of buffer: %p\n", buffer);
strcpy(buffer, input);
printf("done copying\n");
}

int main(int argc, char **argv) {
if (argc < 2) {
printf("usage: %s input\n", argv[0]);
return 1;
}
crash(argv[1]);
printf("returned safely\n");
return 0;
}



دستورات اجرا و تحلیل

gcc -g file4.c -o file4

gdb --args ./file4 $(python3 -c "print('A'*40)")


بعد از اجرای برنامه داخل gdb این مراحل رو انجام بدید

break crash

run

info frame

x/32x $rbp

x/32x $rsp

اینجا میبینید که بافر پایین‌ تر از saved RBP قرار داره
هر بایتی که از بافر بیرون بنویسید در اخر به saved RBP و بعد return address میرسه


برای مشاهده کرش

continue


برنامه با خطای segmentation fault کرش میکنه
با دستور زیر مسیر برگشت رو ببینید

backtrace


و با این دستور آخرین آدرس برگشتی رو چک کنید

info registers rip



توضیح کامل

در هنگام اجرای تابع crash سیستم اول RBP فعلی رو ذخیره میکنه
بعد RSP رو به پایین‌ تر منتقل میکنه تا فضای لازم برای متغیر های لوکال فراهم بشه
داخل این فضای جدید بافر قرار داره
وقتی ما داده‌ ای بزرگ‌ تر از اندازه بافر بنویسیم اول داده روی متغیر های لوکال مینویسن بعد روی RBP و بعد روی return address
در لحظه‌ای که تابع میخاد برگرده مقدار اشتباه از روی استک خونده میشه و RIP به آدرسی اشتباه پرش میکنه و همین باعث segmentation fault میشه


بخش جذاب

میتونید در gdb با این دستور تفاوت قبل و بعد از overflow رو ببینید


قبل از strcpy

x/32x $rbp-32


بعد از strcpy

x/32x $rbp-32


میبینید که بایت‌های A تمام فضای بین بافر تا return address رو پر کرده
این همون دلیل کرش برنامه هست

@reverseengine
3
Part 6 Buffer Overflow


Understanding the Crash and the Structure of the Function Frame on the Stack

In this part, we are going to see what exactly happens behind the scenes when a buffer overflow causes a crash. After this part, we should
understand why overwriting data on the stack changes the return address.
What are the components of a function frame?
And how can these components be viewed and analyzed with gdb.

When a function is called in C, the system creates a space on the stack for that function. We call this space the function frame. Each frame contains these parts.

Local variables of the function

Parameter values

Saved RBP or base pointer
for return

Saved return address
which the function returns to after the function completes

If more data is written to the local buffer than the limit, these important values ​​are overwritten in the frame
And as a result, the program crashes on return or jumps to the wrong address

This code helps us see the function frame and crash and analyze it in gdb

#include <stdio.h>
#include <string.h>

void crash(char *input) {
char buffer[16];
printf("address of buffer: %p\n", buffer);
strcpy(buffer, input);
printf("done copying\n");
}

int main(int argc, char **argv) {
if (argc < 2) {
printf("usage: %s input\n", argv[0]);
return 1;
}
crash(argv[1]);
printf("returned safely\n");
return 0;
}


Execution and analysis commands

gcc -g file4.c -o file4

gdb --args ./file4 $(python3 -c "print('A'*40)")


After running the program in gdb, perform these steps

break crash

run

info frame

x/32x $rbp

x/32x $rsp


Here you can see that the buffer is below the saved RBP

Every byte you write out of the buffer will eventually reach the saved RBP and then the return address

To view the crash

continue


The program crashes with a segmentation fault error

See the return path with the following command

backtrace


And check the last return address with this command

info registers rip


Full explanation

When executing the crash function, the system first saves the current RBP

Then it moves the RSP down to provide the necessary space for local variables

In this new buffer space, Yes
When we write data larger than the buffer size, first the data is written to local variables, then to RBP, and then to the return address
At the moment the function wants to return, the wrong value is read from the stack and RIP jumps to the wrong address, which causes a segmentation fault

Interesting part

You can see the difference before and after the overflow in gdb with this command

Before strcpy
x/32x $rbp-32


After strcpy
x/32x $rbp-32


You can see that the A bytes have filled all the space between the buffer and the return address

This is the reason for the program crash

@reverseengine
4
Acunetix Premium Plus OnPremise with API Discovery

v 25.8.250820089

https://cloud.proxy-bar.org/s/5KhtUcpx3Cxln0Y
3
2