2015-09-24 1 views
4

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

адрес, который отображается с помощью GDB отличается, чем если бы я просто сделал это в коде:

Точный код:

#include<stdio.h> 

int main() { 
    char buffer[20]; 
    printf("%p\n", buffer); // 0xbffff320 

    return 0; 
} 

Однако в БГД, если я:

p &buffer 

Я получаю: 0xbffff330

Почему есть разница, и это испортит моя переполнение буфера переполнения?

У меня есть ALSR и защита стека отключена.

Спасибо.

EDIT 1: Даже когда я пошагово БГД и он встречает линию печати, я получаю 0xbffff320 как адрес

EDIT 2:

Окружающая среда: Ubuntu Linux 9 образ работы в виртуальном окне на окнах 7 .

GDB версии: 6,8-Debian

Составлено с использованием GCC, таких как: gcc -g -fno-stack-protector filename.c выполнить сразу: ./a.out адрес печать изд: 0xbffff320

Затем открыть в отладчике, как это: gdb ./a.out введите b main затем run затем p &buffer

Тогда адрес 0xbffff330

Edit 3:

Это журнал GDB для воспроизводство:

$ gdb ./a.out

б главного

выполнения

р & буфер/* адрес здесь отличается от того, что отображается, если я запускаю исполняемый */

пошагово программы PRINTF о/* адрес здесь же как p & буфер, но отличается от того, что напечатано при запуске программы */

+1

Вы имеете в виду, что во время одного и того же запуска в формате gdb printf и gdb выводит разные значения? – hdl

+0

Опираясь на _undefined behaviour_ - неплохая идея.Во всяком случае, я не думаю, что SO должно помочь использовать уязвимости. – Olaf

+0

@ Hdl, правильно. Они печатают разные значения. В том же компиляции и исполнении. – Kingamere

ответ

5

Вопрос, как я понимаю, является причиной того, что адрес локальной переменной в main отличается от того, когда программа запускается из оболочки в зависимости от того, когда она запускается из gdb.

Вот пример программы, чтобы показать разницу:

[email protected]:~$ cat s.c 
#include<stdio.h> 

int main(int argc, char **argv) { 
    char buffer[20]; 
    system("env"); 
    printf("%s %p\n", argv[0], buffer); 

    return 0; 
} 

Мы запустить его в чистой окружающей среде. (Я также отключил ASLR).

[email protected]:~$ env -i sh 
$ ./s 
PWD=/home/mp 
./s 0xbffffe48 

 

$ gdb ./s 
(gdb) run 
Starting program: /home/mp/s 
COLUMNS=80 
PWD=/home/mp 
LINES=42 
/home/mp/s 0xbffffe08 

Выход из print &buffer команды GDB является такой же, как идея программы адреса, но они оба отличаются от того, когда программа была запущена в оболочке.

(gdb) b 6 
Breakpoint 1 at 0x804849c: file s.c, line 6. 
(gdb) run 
Starting program: /home/mp/s 
COLUMNS=80 
PWD=/home/mp 
LINES=42 

Breakpoint 1, main (argc=1, argv=0xbffffed4) at s.c:6 
6  printf("%s %p\n", argv[0], buffer); 
(gdb) p &buffer 
$1 = (char (*)[20]) 0xbffffe08 
(gdb) n 
/home/mp/s 0xbffffe08 
8  return 0; 

Есть несколько вещей, способствующих разницы:

  • GDB является вызовом программы с абсолютным путевым, поэтому массив ARGV больше.
  • gdb устанавливает (или в этом случае добавляет) две переменные среды. Это делается в readline/shell.c:sh_set_lines_and_columns(). Таким образом, массив окружения больше.

Чтобы удалить эти две переменные из окружения, вы можете использовать unset environment или set exec-wrapper запустить env -u .... Таким образом, адреса программы под gdb такие же, как при запуске в оболочке (если мы используем абсолютный путь).

$ `pwd`/s 
PWD=/home/mp 
/home/mp/s 0xbffffe28 

$ gdb `pwd`/s 
(gdb) set exec-wrapper env -u LINES -u COLUMNS 
(gdb) run 
Starting program: /home/mp/s 
PWD=/home/mp 
/home/mp/s 0xbffffe28 
+0

Ahh Я вижу, спасибо. Меня это раздражало. Каковы переменные среды, строки и столбцы? – Kingamere

+1

Да, пакет 'readline', который использует gdb, устанавливает их. Это размеры окна терминала. Я не смотрел, почему это так.Он, вероятно, использует значения внутри, чтобы он мог корректно отображать командную строку, которая так длинна, что требуется больше одной физической линии терминала. –

+0

Полезно знать. Еще раз спасибо – Kingamere

1

Ваш объект массива в вашей системе хранится в стеке. В верхней части стека есть, помимо прочего, среда. Когда вы запустите свою программу с помощью gdb, gdb предоставит другую среду (env var и их значение), которая объясняет разницу адресов.

Вы можете проверить разницу, запустив show environment в gdb и сравнив вывод с командой set в своей оболочке.

+0

Спасибо, я посмотрю на это сейчас. – Kingamere

+0

Так вы говорите, GDB отображает другую среду, а также значения отображаемого GDB гораздо точнее и полнее, чем если бы я только распечатывал код через код? – Kingamere

+0

Вы можете попробовать самостоятельно с помощью своей программы. Запустите свою программу (без 'gdb'), чтобы увидеть адрес. Затем экспортируйте BLA = 'с длинной строкой и снова запустите свою программу (все еще без' gdb'), вы увидите, что адрес теперь другой. – ouah

0

На данный момент, единственная причина, я могу себе представить, являются:

  • вы пытались print &bufferпосле вашей программы прекращается. Решение: попробуйте установить контрольную точку на main, run, next для выполнения printf и print &buffer.
  • Вы сначала запускали вашу программу за пределами gdb, затем запускали ее внутри gdb, но забыли выполнить строку printf с next.
  • ошибка в версии GDB
  • ошибка в версии GCC (GCC может производить неправильные данные отладки: см 1 и 2)
+0

Да, я сделал: «b main», а затем «run», а затем сразу же «p & buffer» – Kingamere

+0

@Ikshvaku, тогда вы выполнили 'printf'instruction с' next'? (см. обновленный ответ) – hdl

+0

Да, я сделал это. Также мой профессор только что ответил и сказал, что GDB добавляет кое-что в нижнюю часть стека, чтобы помочь ему отлаживать должным образом. Но это все еще не объясняет, почему вы не видите разные адреса. – Kingamere

1

Найдено, что это ожидаемое поведение в старых версиях GDB (мой - 6.8-debian), и если вы правильно сконструируете атаку переполнения буфера, вы можете обойти это поведение, и это не будет проблемой.

+0

Не могли бы вы поделиться некоторыми ссылками? Как вы узнали? :) – hdl

+0

Моя единственная ссылка - мой профессор говорит мне, что gdb добавляет некоторые инструкции в нижнюю часть стека, чтобы он мог отлаживать правильно. Я хочу сказать, что в контексте выполнения переполнения буфера это несоответствие адресов не должно сильно влиять на атаку, и вам все равно удастся это сделать. – Kingamere

 Смежные вопросы

  • Нет связанных вопросов^_^