Как отключить патч FORTIFY_SOURCE с помощью ошибки форматной строки

Этот вопрос относится к: Eulogy для форматирования строк из phrack ( http://www.phrack.org/issues.html?issue=67&id=9)

//File: test.c
//gcc -D_FORTIFY_SOURCE=2 -O2
int main(){
  char buf[256];
  fgets(buf, sizeof(buf), stdin);
  printf(buf);
}

Я не понимаю в их статье, как предоставление строки fmt, такой как%1$*269168516$, может отключить бит _IO_FLAGS2_FORTIFY в stdout Структура файла?

Это потому, что когда мы переполняем целочисленное смещение, args_type [offset] может указывать в любом месте памяти, а именно на stdout->_flags2, чтобы установить его в 0?

Если так, как мы можем знать, что нам удалось отключить его? потому что, когда я пытаюсь с этим кодом, я не могу получить segfault, как указано в статье. (опция компиляции: gcc -m32 -z execstack -fno-stack-protector -ggdb -O2 -D_FORTIFY_SOURCE=2 -o prog test.c)

(gdb) disas vprintf
Dump of assembler code for function vprintf:
   0xf7e9ed90 <+0>: push   %ebp
   0xf7e9ed91 <+1>: mov    %esp,%ebp
   0xf7e9ed93 <+3>: push   %ebx
   0xf7e9ed94 <+4>: sub    $0xc,%esp
   0xf7e9ed97 <+7>: mov    0xc(%ebp),%eax
   0xf7e9ed9a <+10>:    call   0xf7f6ac66
   0xf7e9ed9f <+15>:    add    $0x11b255,%ebx
   0xf7e9eda5 <+21>:    mov    %eax,0x8(%esp)
   0xf7e9eda9 <+25>:    mov    0x8(%ebp),%eax
   0xf7e9edac <+28>:    mov    %eax,0x4(%esp)
   0xf7e9edb0 <+32>:    mov    -0x7c(%ebx),%eax
   0xf7e9edb6 <+38>:    mov    (%eax),%eax
   0xf7e9edb8 <+40>:    mov    %eax,(%esp)
   0xf7e9edbb <+43>:    call   0xf7e99a60 <vfprintf>
   0xf7e9edc0 <+48>:    add    $0xc,%esp
   0xf7e9edc3 <+51>:    pop    %ebx
   0xf7e9edc4 <+52>:    pop    %ebp
   0xf7e9edc5 <+53>:    ret

1 ответ

Это потому, что когда мы переполняем целочисленное смещение, args_type [offset] может указывать в любом месте памяти, а именно на stdout->_flags2, чтобы установить его в 0?

Да.

Если так, как мы можем знать, что нам удалось отключить его?

Вы проверяете это с помощью %n в вашей строке формата. Если это не ошибка, то вы добились успеха.

Я не могу получить segfault, как указано в статье

Если вы имеете в виду вход %n не дает вам:

*** %n in writable segment detected ***
Aborted

Тогда у вас нет _FORTIFY_SOURCE правильно включен, чтобы начать с.

Другие вопросы по тегам