امنیتتست نفوذ

آسیب پذیری های مربوط به خواندن و نوشتن نامتعارف

خواندن و نوشتن نامتعارف (Arbitrary Read/Write)

به معنی خواندن و یا نوشتن هر قسمتی از برنامه است که غالبا توسط سازنده برنامه اجازه یا اختیار آن به ما داده نشده باشد. به عنوان مثال می توان به سرریز بافر، format string و خواندن یا نوشتن بر روی قسمت خاصی از حافظه، بعد از یک integer overflow یا یک ورودی نامتعارف اشاره کرد.

معمولا قسمت هایی که اکثر اوقات هدف نوشتن نامتعارف قرار می گیرند عبارتند از: متغیرهای استک، فریم استک (شامل آدرس بازگشت از تابع هم می شود)، متغییرهای حساس، متا داده های یک بلوک heap و همین طور جدول GOT هستند که بسته به ساختار برنامه مورد نظر و الگوریتم برنامه ممکن است هر کدام یا چند مورد را پشت سر هم استفاده کنیم.

خواندن نامتعارف می تواند به اکسپلویت نویسی کمک شایانی کند، کیلاگرها معمولا از همین روش استفاده کرده و قسمتی از رم که بافر خواندن ورودی کیبورد است را خوانده و ذخیره می کنند.

در اکسپلویت heartbleed در پیاده سازی ssl و کتابخانه openssl نیز همین خواندن دلخواه و نامتعارف بود که به info leak قسمتی از کلیدهای خصوصی رمز نگاری شده و امکان رمزگشایی را برای حمله کننده آسان می ساخت. بگذارید چند مثال از خواندن و یا نوشتن نامتعارف و دلخواه را با هم بررسی کنیم.

  • سرریز بافر: اگرچه خیلی قدیمی اما هنوز هم مهم و ضروری است.
  • سرریز عدد: بسیار مهم و معمول حتی در بسیاری از برنامه های امروزی.

سرریز بافر (buffer overflow)

Buffer overflow
Buffer overflow

اگر بافر را به عنوان قسمتی از حافظه که شما انتخاب کرده و اندازه ای مشخص برای آن تعیین کردید در نظر بگیریم، بیش از حد و یا کمتر از حد آن اندازه بنویسیم و یا بخوانیم را به ترتیب buffer overflow و buffer underflow می نامیم. به عنوان مثال آرایه ای 15 خانه ای تعریف کرده ایم، اگر عددی منفی و یا عددی بیش از 15 بعنوان اندیس بدهیم.

برنامه زیر یک مثال از خواندن و نوشتن نامتعارف است:

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

int main()
{
char buffer[100] = {0};
char letters[27] = "abcdefghijklmnopqrstvuwxyz\0";
int choice = 0;
size_t index = 0;

while (choice != -1)
{
printf("give me a letter number: ");
scanf("%d", &choice);
buffer[index] = letters[choice-1];
index++;
printf("%s\n", buffer);
}
return 0;

سرریز عدد (Number overflow)

Number overflow
Number overflow

وقتی یک متغیر عددی به بالاترین حد فضای اختصاص داده شده به آن می رسد، با اضافه شدن بیشتر به کمترین اندازه خودش بر می گردد و از آنجا ادامه می یابد. به عنوان مثال یک متغیر از نوع unsigned char بازه 0 تا 255 را ساپورت می کند، اما وقتی مثلا 250 است و ما 10 تا به آن اضافه می کنیم، به جای 260 عدد 4 را داخل خود ذخیره می کند. چون در ان فضای 8 بیتی جا نمی شود. این باعث می شود با جمع، ضرب و یا منها کردن به عددی کمتر از عدد فعلی در ان متغیر برسیم.

برنامه زیر یک مثال ساده از سرریز عددی است:

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

void pick_steps(char *ret, const char *buf,
int start, int end, int step)
{
for (int j = 0, i = start; i < end; i += step)
ret[j++] = buf[i];
}

int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "%s <sentence> <step>\n", argv[0]);
return 1;
}

char result[200] = {0};
int length = strlen(argv[1]);
if (length >= 200 || length < 1) {
fprintf(stderr,
"Error: sentence should have less than 200 chars.\n");
return 1;
}

int step = atoi(argv[2]);

pick_steps(result, argv[1], 0, length, step);

printf("result: %s\n", result);

return 0;
}

در پستی دیگر این مثال ها را آنالیز و برای آنها اکسپلویت خواهیم نوشت.

یک دیدگاه

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

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


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